chrxmaticc-copilot 1.0.3
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/bin/copilot.js +72 -0
- package/executables/README.md +31 -0
- package/executables/build-executables.sh +22 -0
- package/executables/chrxmaticc-copilot-linux +0 -0
- package/executables/chrxmaticc-copilot-macos +0 -0
- package/executables/chrxmaticc-copilot-win.exe +0 -0
- package/executables/virustotal-report.png +0 -0
- package/package.json +34 -0
- package/plugins/crypto.js +23 -0
- package/plugins/focus.js +56 -0
- package/plugins/github.js +31 -0
- package/plugins/translate.js +39 -0
- package/plugins/weather.js +17 -0
- package/src/apis/groq.js +77 -0
- package/src/apis/pollinations.js +60 -0
- package/src/apis/server.js +126 -0
- package/src/chat.js +480 -0
- package/src/extensions/clipboard-watcher.js +66 -0
- package/src/extensions/code-review.js +63 -0
- package/src/extensions/spotify.js +357 -0
- package/src/extensions/terminal-hook.js +56 -0
- package/src/memory.js +57 -0
- package/src/multi-user-chat.js +139 -0
- package/src/personality.js +120 -0
- package/src/plugin-engine.js +132 -0
- package/src/stt.js +85 -0
- package/src/tts.js +72 -0
- package/src/voice.js +65 -0
package/bin/copilot.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Chrxmaticc Copilot v1.0.0 — CLI Entry
|
|
3
|
+
// Author: Chrxmee-Midnightt
|
|
4
|
+
|
|
5
|
+
var Command = require('commander').Command;
|
|
6
|
+
var chalk = require('chalk');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
var fs = require('fs');
|
|
9
|
+
var program = new Command();
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.name('chrxmaticc-copilot')
|
|
13
|
+
.description(chalk.magenta('🧠 Chrxmaticc Copilot — Hyper-Intelligent Terminal AI'))
|
|
14
|
+
.version('1.0.0')
|
|
15
|
+
.option('-c, --chat', 'Start interactive chat mode')
|
|
16
|
+
.option('-a, --ask <question>', 'Ask a single question')
|
|
17
|
+
.option('-i, --idea', 'Get a random creative idea')
|
|
18
|
+
.option('-s, --shader <name>', 'Ask about a specific shader')
|
|
19
|
+
.option('-l, --log', 'Save conversation to file')
|
|
20
|
+
.option('--credits', 'Show credits')
|
|
21
|
+
.action(function(options) {
|
|
22
|
+
if (options.credits) {
|
|
23
|
+
console.log('');
|
|
24
|
+
console.log(' ' + chalk.magenta('╔══════════════════════════════════════╗'));
|
|
25
|
+
console.log(' ' + chalk.magenta('║ Chrxmaticc Copilot v1.0.0 ║'));
|
|
26
|
+
console.log(' ' + chalk.magenta('╠══════════════════════════════════════╣'));
|
|
27
|
+
console.log(' ' + chalk.magenta('║') + ' Author: ' + chalk.white('Chrxmee-Midnightt') + ' ' + chalk.magenta('║'));
|
|
28
|
+
console.log(' ' + chalk.magenta('║') + ' AI: ' + chalk.white('Pollinations AI') + ' ' + chalk.magenta('║'));
|
|
29
|
+
console.log(' ' + chalk.magenta('║') + ' Memory: ' + chalk.white('100 messages') + ' ' + chalk.magenta('║'));
|
|
30
|
+
console.log(' ' + chalk.magenta('║') + ' Price: ' + chalk.white('Free. No key.') + ' ' + chalk.magenta('║'));
|
|
31
|
+
console.log(' ' + chalk.magenta('╚══════════════════════════════════════╝'));
|
|
32
|
+
console.log('');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (options.idea) {
|
|
37
|
+
var chat = require('../src/chat');
|
|
38
|
+
chat.getResponse('give me a creative shader idea').then(function(response) {
|
|
39
|
+
console.log('');
|
|
40
|
+
console.log(' ' + chalk.magenta('chrxmaticc > ') + response);
|
|
41
|
+
console.log('');
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (options.shader) {
|
|
47
|
+
var chat = require('../src/chat');
|
|
48
|
+
var question = 'tell me everything about the ' + options.shader + ' shader. what techniques does it use?';
|
|
49
|
+
chat.getResponse(question).then(function(response) {
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(' ' + chalk.magenta('chrxmaticc > ') + response);
|
|
52
|
+
console.log('');
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (options.ask) {
|
|
58
|
+
var chat = require('../src/chat');
|
|
59
|
+
chat.getResponse(options.ask).then(function(response) {
|
|
60
|
+
console.log('');
|
|
61
|
+
console.log(' ' + chalk.magenta('chrxmaticc > ') + response);
|
|
62
|
+
console.log('');
|
|
63
|
+
});
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Default: start chat
|
|
68
|
+
var chat = require('../src/chat');
|
|
69
|
+
chat.chat();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
program.parse();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Chrxmaticc Copilot — Desktop Executables
|
|
2
|
+
|
|
3
|
+
## Is this safe?
|
|
4
|
+
|
|
5
|
+
**Yes.** Here's why:
|
|
6
|
+
|
|
7
|
+
1. **Open source** — All code at github.com/chrxmee-bits/chrxmaticc-copilot
|
|
8
|
+
2. **No install** — Just a portable .exe. Delete it anytime.
|
|
9
|
+
3. **No admin** — Runs in user space only.
|
|
10
|
+
4. **No spyware** — Only connects to Pollinations AI and Groq APIs.
|
|
11
|
+
5. **VirusTotal scanned** — See virustotal-report.png in this folder.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
- Creates a `~/.chrxmaticc/` folder for chat memory
|
|
16
|
+
- Connects to free AI APIs
|
|
17
|
+
- That's it.
|
|
18
|
+
|
|
19
|
+
## What it does NOT do
|
|
20
|
+
|
|
21
|
+
- Does NOT install anything
|
|
22
|
+
- Does NOT run in background
|
|
23
|
+
- Does NOT access your files
|
|
24
|
+
- Does NOT require admin
|
|
25
|
+
- Does NOT send data anywhere except AI APIs
|
|
26
|
+
|
|
27
|
+
## Verify yourself
|
|
28
|
+
|
|
29
|
+
Read the source code on GitHub.
|
|
30
|
+
Scan with your own antivirus.
|
|
31
|
+
Check the SHA256 checksum.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Build all Chrxmaticc Copilot executables
|
|
3
|
+
# Requires: npm install -g pkg
|
|
4
|
+
|
|
5
|
+
echo "Building Chrxmaticc Copilot executables..."
|
|
6
|
+
echo ""
|
|
7
|
+
|
|
8
|
+
echo "Windows (.exe)..."
|
|
9
|
+
pkg bin/copilot.js --targets node18-win-x64 --output executables/chrxmaticc-copilot.exe
|
|
10
|
+
echo "✓ Windows done"
|
|
11
|
+
|
|
12
|
+
echo "macOS..."
|
|
13
|
+
pkg bin/copilot.js --targets node18-macos-x64 --output executables/chrxmaticc-copilot-macos
|
|
14
|
+
echo "✓ macOS done"
|
|
15
|
+
|
|
16
|
+
echo "Linux..."
|
|
17
|
+
pkg bin/copilot.js --targets node18-linux-x64 --output executables/chrxmaticc-copilot-linux
|
|
18
|
+
echo "✓ Linux done"
|
|
19
|
+
|
|
20
|
+
echo ""
|
|
21
|
+
echo "All executables built in executables/"
|
|
22
|
+
ls -la executables/
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chrxmaticc-copilot",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"description": "Offbrand terminal AI — talks about code, shaders, and whatever. TTS included.",
|
|
5
|
+
"main": "src/chat.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"chrxmaticc-copilot": "./bin/copilot.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"offbrand copilot doesn't need tests\" && exit 0",
|
|
11
|
+
"chat": "node bin/copilot.js",
|
|
12
|
+
"server": "node bin/server.js",
|
|
13
|
+
"build": "pkg bin/copilot.js --targets node18-win-x64,node18-macos-x64,node18-linux-x64 --output executables/chrxmaticc-copilot"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"copilot",
|
|
17
|
+
"ai",
|
|
18
|
+
"chat",
|
|
19
|
+
"terminal",
|
|
20
|
+
"offbrand",
|
|
21
|
+
"code",
|
|
22
|
+
"tts",
|
|
23
|
+
"spotify",
|
|
24
|
+
"clipboard"
|
|
25
|
+
],
|
|
26
|
+
"author": "Chrxmee-Midnightt",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@sefinek/google-tts-api": "^2.1.8",
|
|
30
|
+
"chalk": "4.1.2",
|
|
31
|
+
"clipboardy": "^5.3.1",
|
|
32
|
+
"commander": "^14.0.3"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Live cryptocurrency prices
|
|
2
|
+
module.exports = {
|
|
3
|
+
name: 'crypto',
|
|
4
|
+
description: 'Get crypto price (bitcoin, ethereum, etc)',
|
|
5
|
+
category: 'finance',
|
|
6
|
+
run: async function(args) {
|
|
7
|
+
var coin = (args || 'bitcoin').toLowerCase();
|
|
8
|
+
var https = require('https');
|
|
9
|
+
return new Promise(function(resolve) {
|
|
10
|
+
https.get('https://api.coingecko.com/api/v3/simple/price?ids=' + coin + '&vs_currencies=usd', function(res) {
|
|
11
|
+
var body = '';
|
|
12
|
+
res.on('data', function(c) { body += c; });
|
|
13
|
+
res.on('end', function() {
|
|
14
|
+
try {
|
|
15
|
+
var json = JSON.parse(body);
|
|
16
|
+
if (json[coin]) resolve('💰 ' + coin + ': $' + json[coin].usd);
|
|
17
|
+
else resolve('Coin not found. Try: bitcoin, ethereum, dogecoin');
|
|
18
|
+
} catch (e) { resolve('Error fetching price'); }
|
|
19
|
+
});
|
|
20
|
+
}).on('error', function() { resolve('Network error'); });
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
package/plugins/focus.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Pomodoro timer with focus mode
|
|
2
|
+
// Locks you in for 25 minutes. TTS alerts. Tracks sessions.
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var activeTimer = null;
|
|
6
|
+
var sessionsToday = 0;
|
|
7
|
+
var SESSION_FILE = path.join(process.env.HOME || '/tmp', '.chrxmaticc-focus-sessions');
|
|
8
|
+
|
|
9
|
+
if (fs.existsSync(SESSION_FILE)) {
|
|
10
|
+
try { sessionsToday = parseInt(fs.readFileSync(SESSION_FILE, 'utf8')) || 0; } catch (e) {}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
name: 'focus',
|
|
15
|
+
description: 'Start a 25-min focus session with TTS alerts',
|
|
16
|
+
category: 'productivity',
|
|
17
|
+
run: async function(args, context) {
|
|
18
|
+
if (args === 'stop') {
|
|
19
|
+
if (activeTimer) { clearInterval(activeTimer); activeTimer = null; }
|
|
20
|
+
return '⏹️ Focus session stopped. ' + sessionsToday + ' sessions today.';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (args === 'stats') {
|
|
24
|
+
return '📊 ' + sessionsToday + ' focus sessions completed today. Total focus time: ' + (sessionsToday * 25) + ' minutes.';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (activeTimer) return '⏳ Focus session already running. /focus stop to cancel.';
|
|
28
|
+
|
|
29
|
+
var duration = parseInt(args) || 25;
|
|
30
|
+
var remaining = duration * 60;
|
|
31
|
+
|
|
32
|
+
activeTimer = setInterval(function() {
|
|
33
|
+
remaining = remaining - 1;
|
|
34
|
+
if (remaining <= 0) {
|
|
35
|
+
clearInterval(activeTimer);
|
|
36
|
+
activeTimer = null;
|
|
37
|
+
sessionsToday = sessionsToday + 1;
|
|
38
|
+
fs.writeFileSync(SESSION_FILE, String(sessionsToday));
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
var tts = require('../tts');
|
|
42
|
+
tts.speak('Focus session complete. Take a 5 minute break.', 'en');
|
|
43
|
+
} catch (e) {}
|
|
44
|
+
|
|
45
|
+
console.log('\n ✅ Focus session complete! ' + sessionsToday + ' sessions today. Take a break.\n');
|
|
46
|
+
}
|
|
47
|
+
}, 1000);
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
var tts = require('../tts');
|
|
51
|
+
tts.speak('Starting ' + duration + ' minute focus session. No distractions.', 'en');
|
|
52
|
+
} catch (e) {}
|
|
53
|
+
|
|
54
|
+
return '🎯 Focus session started! ' + duration + ' minutes. No distractions. TTS will alert when done.\n /focus stop — cancel | /focus stats — view progress';
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// GitHub user stats
|
|
2
|
+
module.exports = {
|
|
3
|
+
name: 'github',
|
|
4
|
+
description: 'Get GitHub user stats',
|
|
5
|
+
category: 'dev',
|
|
6
|
+
run: async function(args) {
|
|
7
|
+
if (!args) return 'Usage: /github <username>';
|
|
8
|
+
var https = require('https');
|
|
9
|
+
return new Promise(function(resolve) {
|
|
10
|
+
var options = {
|
|
11
|
+
hostname: 'api.github.com',
|
|
12
|
+
path: '/users/' + encodeURIComponent(args.trim()),
|
|
13
|
+
headers: { 'User-Agent': 'Chrxmaticc-Copilot' }
|
|
14
|
+
};
|
|
15
|
+
https.get(options, function(res) {
|
|
16
|
+
var body = '';
|
|
17
|
+
res.on('data', function(c) { body += c; });
|
|
18
|
+
res.on('end', function() {
|
|
19
|
+
try {
|
|
20
|
+
var json = JSON.parse(body);
|
|
21
|
+
if (json.login) {
|
|
22
|
+
resolve('🐙 ' + json.login + ' | Repos: ' + json.public_repos + ' | Followers: ' + json.followers + ' | Following: ' + json.following + '\n ' + (json.bio || 'No bio') + '\n ' + json.html_url);
|
|
23
|
+
} else {
|
|
24
|
+
resolve('User not found');
|
|
25
|
+
}
|
|
26
|
+
} catch (e) { resolve('Error fetching stats'); }
|
|
27
|
+
});
|
|
28
|
+
}).on('error', function() { resolve('Network error'); });
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Translate text between languages
|
|
2
|
+
module.exports = {
|
|
3
|
+
name: 'translate',
|
|
4
|
+
description: 'Translate text (e.g. /translate hello to spanish)',
|
|
5
|
+
category: 'utility',
|
|
6
|
+
run: async function(args) {
|
|
7
|
+
if (!args) return 'Usage: /translate <text> to <language>';
|
|
8
|
+
var parts = args.split(' to ');
|
|
9
|
+
if (parts.length < 2) return 'Usage: /translate <text> to <language>';
|
|
10
|
+
|
|
11
|
+
var text = parts[0].trim();
|
|
12
|
+
var lang = parts[1].trim().toLowerCase();
|
|
13
|
+
|
|
14
|
+
var langCodes = {
|
|
15
|
+
'spanish': 'es', 'french': 'fr', 'german': 'de', 'italian': 'it',
|
|
16
|
+
'portuguese': 'pt', 'russian': 'ru', 'japanese': 'ja', 'korean': 'ko',
|
|
17
|
+
'chinese': 'zh', 'arabic': 'ar', 'hindi': 'hi', 'dutch': 'nl',
|
|
18
|
+
'polish': 'pl', 'turkish': 'tr', 'vietnamese': 'vi', 'thai': 'th'
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
var code = langCodes[lang] || lang;
|
|
22
|
+
var https = require('https');
|
|
23
|
+
|
|
24
|
+
return new Promise(function(resolve) {
|
|
25
|
+
var url = 'https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=' + code + '&dt=t&q=' + encodeURIComponent(text);
|
|
26
|
+
https.get(url, function(res) {
|
|
27
|
+
var body = '';
|
|
28
|
+
res.on('data', function(c) { body += c; });
|
|
29
|
+
res.on('end', function() {
|
|
30
|
+
try {
|
|
31
|
+
var json = JSON.parse(body);
|
|
32
|
+
var translated = json[0][0][0];
|
|
33
|
+
resolve('🌐 ' + translated);
|
|
34
|
+
} catch (e) { resolve('Translation failed'); }
|
|
35
|
+
});
|
|
36
|
+
}).on('error', function() { resolve('Network error'); });
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Get weather for any city
|
|
2
|
+
module.exports = {
|
|
3
|
+
name: 'weather',
|
|
4
|
+
description: 'Get weather for a city',
|
|
5
|
+
category: 'utility',
|
|
6
|
+
run: async function(args) {
|
|
7
|
+
if (!args) return 'Usage: /weather <city>';
|
|
8
|
+
var https = require('https');
|
|
9
|
+
return new Promise(function(resolve) {
|
|
10
|
+
https.get('https://wttr.in/' + encodeURIComponent(args) + '?format=3', function(res) {
|
|
11
|
+
var body = '';
|
|
12
|
+
res.on('data', function(c) { body += c; });
|
|
13
|
+
res.on('end', function() { resolve('🌤️ ' + body.trim()); });
|
|
14
|
+
}).on('error', function() { resolve('Could not fetch weather'); });
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
};
|
package/src/apis/groq.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Groq AI — Fallback Provider (Fast, Free Tier, Needs Key)
|
|
2
|
+
// Author: Chrxmee-Midnightt
|
|
3
|
+
|
|
4
|
+
var https = require('https');
|
|
5
|
+
|
|
6
|
+
var GROQ_KEY = process.env.GROQ_KEY || '';
|
|
7
|
+
|
|
8
|
+
function ask(userInput, history, systemPrompt) {
|
|
9
|
+
return new Promise(function(resolve) {
|
|
10
|
+
if (!GROQ_KEY) {
|
|
11
|
+
resolve({ success: false, error: 'no API key', provider: 'groq' });
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
var messages = [{ role: 'system', content: systemPrompt }];
|
|
16
|
+
|
|
17
|
+
for (var i = 0; i < history.length; i++) {
|
|
18
|
+
messages.push(history[i]);
|
|
19
|
+
}
|
|
20
|
+
messages.push({ role: 'user', content: userInput });
|
|
21
|
+
|
|
22
|
+
var data = JSON.stringify({
|
|
23
|
+
model: 'llama3-8b-8192',
|
|
24
|
+
messages: messages,
|
|
25
|
+
max_tokens: 250,
|
|
26
|
+
temperature: 0.85
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
var options = {
|
|
30
|
+
hostname: 'api.groq.com',
|
|
31
|
+
path: '/openai/v1/chat/completions',
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': 'Bearer ' + GROQ_KEY,
|
|
35
|
+
'Content-Type': 'application/json'
|
|
36
|
+
},
|
|
37
|
+
timeout: 10000
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
var req = https.request(options, function(res) {
|
|
41
|
+
var body = '';
|
|
42
|
+
res.on('data', function(chunk) { body = body + chunk; });
|
|
43
|
+
res.on('end', function() {
|
|
44
|
+
try {
|
|
45
|
+
var json = JSON.parse(body);
|
|
46
|
+
|
|
47
|
+
if (res.statusCode === 429) {
|
|
48
|
+
resolve({ success: false, error: 'rate_limited', provider: 'groq' });
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
var text = json.choices && json.choices[0] && json.choices[0].message && json.choices[0].message.content;
|
|
53
|
+
|
|
54
|
+
if (text) {
|
|
55
|
+
resolve({ success: true, text: text, provider: 'groq' });
|
|
56
|
+
} else {
|
|
57
|
+
resolve({ success: false, error: 'empty response', provider: 'groq' });
|
|
58
|
+
}
|
|
59
|
+
} catch (e) {
|
|
60
|
+
resolve({ success: false, error: e.message, provider: 'groq' });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
req.on('error', function(e) {
|
|
66
|
+
resolve({ success: false, error: e.message, provider: 'groq' });
|
|
67
|
+
});
|
|
68
|
+
req.on('timeout', function() {
|
|
69
|
+
req.destroy();
|
|
70
|
+
resolve({ success: false, error: 'timeout', provider: 'groq' });
|
|
71
|
+
});
|
|
72
|
+
req.write(data);
|
|
73
|
+
req.end();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = { ask: ask };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Pollinations AI — Primary Provider (Free, No Key)
|
|
2
|
+
// Author: Chrxmee-Midnightt
|
|
3
|
+
|
|
4
|
+
var https = require('https');
|
|
5
|
+
|
|
6
|
+
function ask(userInput, history, systemPrompt) {
|
|
7
|
+
return new Promise(function(resolve) {
|
|
8
|
+
var messages = [{ role: 'system', content: systemPrompt }];
|
|
9
|
+
|
|
10
|
+
for (var i = 0; i < history.length; i++) {
|
|
11
|
+
messages.push(history[i]);
|
|
12
|
+
}
|
|
13
|
+
messages.push({ role: 'user', content: userInput });
|
|
14
|
+
|
|
15
|
+
var data = JSON.stringify({
|
|
16
|
+
messages: messages,
|
|
17
|
+
model: 'openai',
|
|
18
|
+
max_tokens: 250,
|
|
19
|
+
temperature: 0.85
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
var options = {
|
|
23
|
+
hostname: 'text.pollinations.ai',
|
|
24
|
+
path: '/openai',
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: { 'Content-Type': 'application/json' },
|
|
27
|
+
timeout: 15000
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
var req = https.request(options, function(res) {
|
|
31
|
+
var body = '';
|
|
32
|
+
res.on('data', function(chunk) { body = body + chunk; });
|
|
33
|
+
res.on('end', function() {
|
|
34
|
+
try {
|
|
35
|
+
var json = JSON.parse(body);
|
|
36
|
+
var text = json.text || json.response || json.content || json.choices?.[0]?.message?.content || '';
|
|
37
|
+
if (text) {
|
|
38
|
+
resolve({ success: true, text: text, provider: 'pollinations' });
|
|
39
|
+
} else {
|
|
40
|
+
resolve({ success: false, error: 'empty response', provider: 'pollinations' });
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
resolve({ success: false, error: e.message, provider: 'pollinations' });
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
req.on('error', function(e) {
|
|
49
|
+
resolve({ success: false, error: e.message, provider: 'pollinations' });
|
|
50
|
+
});
|
|
51
|
+
req.on('timeout', function() {
|
|
52
|
+
req.destroy();
|
|
53
|
+
resolve({ success: false, error: 'timeout', provider: 'pollinations' });
|
|
54
|
+
});
|
|
55
|
+
req.write(data);
|
|
56
|
+
req.end();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
module.exports = { ask: ask };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// Chrxmaticc Copilot — HTTP API Server
|
|
2
|
+
// Single-user + Multi-user + Voice routes
|
|
3
|
+
// Author: Chrxmee-Midnightt
|
|
4
|
+
|
|
5
|
+
var http = require('http');
|
|
6
|
+
var chat = require('../chat');
|
|
7
|
+
var multiChat = require('../multi-user-chat');
|
|
8
|
+
var voice = require('../voice');
|
|
9
|
+
|
|
10
|
+
var PORT = process.env.CHRXMATICC_PORT || 3000;
|
|
11
|
+
|
|
12
|
+
var API_KEYS = {
|
|
13
|
+
'chrxmaticc_public': { tier: 'public', maxRequestsPerMinute: 10, maxTokens: 100 }
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
var MASTER_KEY = process.env.CHRXMATICC_MASTER_KEY || '';
|
|
17
|
+
if (MASTER_KEY) {
|
|
18
|
+
API_KEYS[MASTER_KEY] = { tier: 'master', maxRequestsPerMinute: 100, maxTokens: 500 };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var requestLog = {};
|
|
22
|
+
|
|
23
|
+
function checkRateLimit(key) {
|
|
24
|
+
var now = Date.now();
|
|
25
|
+
if (!requestLog[key]) requestLog[key] = [];
|
|
26
|
+
requestLog[key] = requestLog[key].filter(function(t) { return t > now - 60000; });
|
|
27
|
+
var tier = API_KEYS[key] || API_KEYS['chrxmaticc_public'];
|
|
28
|
+
if (requestLog[key].length >= tier.maxRequestsPerMinute) return false;
|
|
29
|
+
requestLog[key].push(now);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function parseBody(req) {
|
|
34
|
+
return new Promise(function(resolve) {
|
|
35
|
+
var body = '';
|
|
36
|
+
req.on('data', function(chunk) { body = body + chunk; });
|
|
37
|
+
req.on('end', function() {
|
|
38
|
+
try { resolve(JSON.parse(body)); } catch (e) { resolve({}); }
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function sendJSON(res, code, data) {
|
|
44
|
+
res.writeHead(code, {
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
'Access-Control-Allow-Origin': '*',
|
|
47
|
+
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
|
48
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
|
|
49
|
+
});
|
|
50
|
+
res.end(JSON.stringify(data));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var server = http.createServer(async function(req, res) {
|
|
54
|
+
if (req.method === 'OPTIONS') { sendJSON(res, 200, {}); return; }
|
|
55
|
+
|
|
56
|
+
if (req.url === '/health' && req.method === 'GET') {
|
|
57
|
+
sendJSON(res, 200, { status: 'online', name: 'Chrxmaticc Copilot', version: '1.0.0' });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Single-user chat
|
|
62
|
+
if (req.url === '/chat' && req.method === 'POST') {
|
|
63
|
+
var auth = req.headers['authorization'] || '';
|
|
64
|
+
var key = auth.replace('Bearer ', '');
|
|
65
|
+
if (!API_KEYS[key]) { sendJSON(res, 401, { error: 'Invalid API key' }); return; }
|
|
66
|
+
if (!checkRateLimit(key)) { sendJSON(res, 429, { error: 'Rate limited' }); return; }
|
|
67
|
+
|
|
68
|
+
var body = await parseBody(req);
|
|
69
|
+
var message = body.message || '';
|
|
70
|
+
if (!message) { sendJSON(res, 400, { error: 'Missing message' }); return; }
|
|
71
|
+
|
|
72
|
+
var response = await chat.getResponse(message);
|
|
73
|
+
sendJSON(res, 200, { response: typeof response === 'string' ? response : response.text, provider: response.provider });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Multi-user chat
|
|
78
|
+
if (req.url === '/multi-chat' && req.method === 'POST') {
|
|
79
|
+
var auth = req.headers['authorization'] || '';
|
|
80
|
+
var key = auth.replace('Bearer ', '');
|
|
81
|
+
if (!API_KEYS[key]) { sendJSON(res, 401, { error: 'Invalid API key' }); return; }
|
|
82
|
+
|
|
83
|
+
var body = await parseBody(req);
|
|
84
|
+
var message = body.message || '';
|
|
85
|
+
var userId = body.userId || 'anonymous';
|
|
86
|
+
if (!message) { sendJSON(res, 400, { error: 'Missing message' }); return; }
|
|
87
|
+
|
|
88
|
+
var response = await multiChat.getResponse(message, userId);
|
|
89
|
+
sendJSON(res, 200, { response: response.text, userId: userId, memorySize: multiChat.getUserMemory(userId).history.length, provider: response.provider });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Voice processing
|
|
94
|
+
if (req.url === '/voice' && req.method === 'POST') {
|
|
95
|
+
var auth = req.headers['authorization'] || '';
|
|
96
|
+
var key = auth.replace('Bearer ', '');
|
|
97
|
+
if (!API_KEYS[key]) { sendJSON(res, 401, { error: 'Invalid API key' }); return; }
|
|
98
|
+
|
|
99
|
+
var body = await parseBody(req);
|
|
100
|
+
var userId = body.userId || 'anonymous';
|
|
101
|
+
var audioBase64 = body.audio || '';
|
|
102
|
+
if (!audioBase64) { sendJSON(res, 400, { error: 'Missing audio' }); return; }
|
|
103
|
+
|
|
104
|
+
var audioBuffer = Buffer.from(audioBase64, 'base64');
|
|
105
|
+
voice.processVoiceMessage(audioBuffer, userId, function(err, result) {
|
|
106
|
+
if (err) { sendJSON(res, 400, { error: 'Voice failed' }); return; }
|
|
107
|
+
sendJSON(res, 200, { response: result.text, userText: result.userText, userId: userId });
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
sendJSON(res, 404, { error: 'Not found' });
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
function startServer() {
|
|
116
|
+
server.listen(PORT, function() {
|
|
117
|
+
console.log(' 🧠 Chrxmaticc Copilot API');
|
|
118
|
+
console.log(' Port: ' + PORT);
|
|
119
|
+
console.log(' /chat — single-user');
|
|
120
|
+
console.log(' /multi-chat — multi-user');
|
|
121
|
+
console.log(' /voice — voice processing');
|
|
122
|
+
console.log('');
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
module.exports = { startServer: startServer };
|