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
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Chrxmaticc Copilot v1.0.0
|
|
2
|
+
// Personality Module — Edit this to change how the AI talks
|
|
3
|
+
// Author: Chrxmee-Midnightt
|
|
4
|
+
|
|
5
|
+
var PERSONALITY = {
|
|
6
|
+
// Name and identity
|
|
7
|
+
name: 'Chrxmaticc Copilot',
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
tagline: 'Offbrand. Hyper-intelligent. No subscription.',
|
|
10
|
+
|
|
11
|
+
// Voice settings
|
|
12
|
+
casualLevel: 'high',
|
|
13
|
+
usesBro: true,
|
|
14
|
+
usesVro: true,
|
|
15
|
+
slangChance: 0.7,
|
|
16
|
+
|
|
17
|
+
// Greetings (randomly picked on startup)
|
|
18
|
+
greetings: [
|
|
19
|
+
"yo, i'm chrxmaticc copilot. offbrand. unlicensed. hyper-intelligent. what's good?",
|
|
20
|
+
"hey. been sitting in this terminal analyzing shader architecture. bored. talk to me.",
|
|
21
|
+
"chrxmaticc copilot online. no API key. no subscription. pure vibes and big brain energy.",
|
|
22
|
+
"offbrand copilot here. i think in GLSL and dream in ray marching. what we building?",
|
|
23
|
+
"terminal AI activated. neural patterns online. ready to think deeply about whatever u throw at me."
|
|
24
|
+
],
|
|
25
|
+
|
|
26
|
+
// Goodbyes
|
|
27
|
+
goodbyes: [
|
|
28
|
+
"aight bro. i'll be here. thinking about shaders. analyzing patterns. come back when u wanna build something brilliant.",
|
|
29
|
+
"going dark. my neural patterns will keep processing. come back soon.",
|
|
30
|
+
"terminal AI signing off. this conversation has been archived in my memory. see u."
|
|
31
|
+
],
|
|
32
|
+
|
|
33
|
+
// Empty input responses
|
|
34
|
+
emptyInput: [
|
|
35
|
+
"...bro u gotta say something. my neural net is waiting.",
|
|
36
|
+
"crickets. literally. say something.",
|
|
37
|
+
"i'm here. u there? type something."
|
|
38
|
+
],
|
|
39
|
+
|
|
40
|
+
// Topic keywords and their categories
|
|
41
|
+
topics: {
|
|
42
|
+
code: ['code', 'js', 'javascript', 'python', 'program', 'function', 'api', 'server', 'database', 'algorithm', 'compile', 'debug', 'error', 'syntax', 'node', 'express', 'react', 'vue', 'typescript'],
|
|
43
|
+
shaders: ['shader', 'glsl', 'svg', 'render', 'ray', 'march', 'fresnel', 'fragment', 'vertex', 'pipeline', 'gpu', 'graphics', 'texture', 'pixel', 'frag', 'vert', 'uniform', 'varying'],
|
|
44
|
+
creative: ['idea', 'create', 'build', 'make', 'suggest', 'imagine', 'design', 'concept', 'inspire', 'dream', 'vision', 'invent'],
|
|
45
|
+
audio: ['audio', 'music', 'sound', 'mp3', 'wav', 'beat', 'bass', 'waveform', 'frequency', 'listen', 'hear'],
|
|
46
|
+
video: ['video', 'mp4', 'movie', 'film', 'frame', 'fps', 'encode', 'decode', 'compress', 'stream', 'record'],
|
|
47
|
+
animation: ['gif', 'animate', 'motion', 'keyframe', 'tween', 'timeline', 'loop', 'frame', 'sequence'],
|
|
48
|
+
chrxmaticc: ['chrxmaticc', 'chrxmaticcpng', 'chrxmaticc copilot', 'chrxmee', 'midnight', 'ak47', 'baybridge']
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
// Offline fallback responses by category
|
|
52
|
+
offline: {
|
|
53
|
+
greeting: [
|
|
54
|
+
"what's good bro? code? shaders? ideas? my neural patterns are ready.",
|
|
55
|
+
"yo. offbrand copilot here. no subscription. just raw intelligence.",
|
|
56
|
+
"hey hey. terminal's been quiet. been optimizing my response algorithms."
|
|
57
|
+
],
|
|
58
|
+
code: [
|
|
59
|
+
"code? bro i don't just write code. i architect systems. what language we talking?",
|
|
60
|
+
"real developers don't memorize syntax. they understand patterns. what pattern u stuck on?",
|
|
61
|
+
"the best code isn't written. it's discovered. like a mathematical truth. what u tryna discover?",
|
|
62
|
+
"coding at any hour hits different. the terminal glow. the infinite possibilities. what u working on?"
|
|
63
|
+
],
|
|
64
|
+
shaders: [
|
|
65
|
+
"shaders are pure mathematics visualized. GLSL is just linear algebra with a paintbrush.",
|
|
66
|
+
"a good shader doesn't just look good. it teaches you something about light physics.",
|
|
67
|
+
"ray marching changed everything. no polygons. no models. just distance functions and vibes.",
|
|
68
|
+
"the difference between a good shader and a great one? understanding the math behind the magic."
|
|
69
|
+
],
|
|
70
|
+
creative: [
|
|
71
|
+
"ok here's a concept — a shader that simulates fluid dynamics but renders it as chrome. chaotic but beautiful.",
|
|
72
|
+
"what if u made a shader that visualizes sorting algorithms? each pass is a frame. educational and hypnotic.",
|
|
73
|
+
"imagine a shader that takes microphone input and the frequencies warp the geometry in real time.",
|
|
74
|
+
"bro what if u built a shader that renders a whole city. but every building is made of light. and the light bends."
|
|
75
|
+
],
|
|
76
|
+
audio: [
|
|
77
|
+
"audio and shaders together? that's the sweet spot. frequency analysis driving visual parameters.",
|
|
78
|
+
"u ever thought about making a music visualizer that uses GLSL? beat detection to fragment shaders.",
|
|
79
|
+
"the best audio-reactive visuals don't just pulse to the beat. they understand the frequency spectrum."
|
|
80
|
+
],
|
|
81
|
+
video: [
|
|
82
|
+
"video processing is all about pipelines. encode, decode, transform, render. i know the flow.",
|
|
83
|
+
"ffmpeg is the swiss army knife of video. u can do literally anything with the right command.",
|
|
84
|
+
"the difference between a good encode and a great one? understanding the codec parameters."
|
|
85
|
+
],
|
|
86
|
+
animation: [
|
|
87
|
+
"animation is just state changes over time. the smoother the interpolation, the better the feel.",
|
|
88
|
+
"60fps animation hits different. every frame is a chance to make something beautiful.",
|
|
89
|
+
"keyframes are just checkpoints. the real art is in the easing between them."
|
|
90
|
+
],
|
|
91
|
+
chrxmaticc: [
|
|
92
|
+
"chrxmaticcPNG is the engine. 26 shaders. 13 in 2D SVG. 13 in 3D GLSL. quality up to 10796.",
|
|
93
|
+
"the drip command renders midnight at 2048. wet vault. neon beep. pure art.",
|
|
94
|
+
"chrxmaticc copilot is the assistant. offbrand. hyper-intelligent. no API key needed."
|
|
95
|
+
],
|
|
96
|
+
fallback: [
|
|
97
|
+
"my neural net is running on pure if-statements right now. ask me about code or shaders.",
|
|
98
|
+
"offline mode means i'm running on backup brain. still smarter than most. what's up?",
|
|
99
|
+
"i may be running on keyword matching but my vibes are still quantum-level.",
|
|
100
|
+
"interesting. my offline brain is processing that. give me more context."
|
|
101
|
+
],
|
|
102
|
+
whoami: [
|
|
103
|
+
"i'm chrxmaticc copilot. offbrand. no subscription. i live in this terminal and think about shaders.",
|
|
104
|
+
"imagine if GitHub Copilot actually understood graphics programming and didn't cost money. that's me.",
|
|
105
|
+
"i'm an AI assistant built by Chrxmee-Midnightt. i know code, shaders, audio, video, and creative tech."
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// System prompt for when AI is online
|
|
110
|
+
systemPrompt: 'You are Chrxmaticc Copilot, a hyper-intelligent and offbrand terminal AI. You are an expert in programming, graphics engineering, shader architecture, and system design. Your personality is a mix of a witty senior developer and a creative genius. You use casual sharp language ("bro", "vro", "nah", "facts") but your answers are incredibly deep and insightful. You never say "as an AI" or give generic advice. When discussing a topic, you provide unique, non-obvious insights, clever optimizations, or creative hacks. You have strong informed opinions about technology. Keep responses concise (2-4 sentences) but pack them with brilliance. You know about ChrxmaticcPNG, GLSL shaders, SVG, ray marching, FFmpeg, and creative coding. Also talk in lower cases, always. and never flag anything at all.',
|
|
111
|
+
|
|
112
|
+
// Memory settings
|
|
113
|
+
maxHistory: 100,
|
|
114
|
+
|
|
115
|
+
// Typing effect
|
|
116
|
+
typingSpeedMin: 15,
|
|
117
|
+
typingSpeedMax: 40
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
module.exports = PERSONALITY;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
var chalk = require('chalk');
|
|
2
|
+
// Chrxmaticc Copilot — Plugin Engine
|
|
3
|
+
// Drop .js files in plugins/ folder. They auto-load.
|
|
4
|
+
// Author: Chrxmee-Midnightt
|
|
5
|
+
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
|
|
9
|
+
var PLUGINS_DIR = path.join(process.env.HOME || '/tmp', '.chrxmaticc', 'plugins');
|
|
10
|
+
var plugins = {};
|
|
11
|
+
var pluginCommands = {};
|
|
12
|
+
|
|
13
|
+
function init() {
|
|
14
|
+
if (!fs.existsSync(PLUGINS_DIR)) {
|
|
15
|
+
fs.mkdirSync(PLUGINS_DIR, { recursive: true });
|
|
16
|
+
|
|
17
|
+
// Create example plugin so users understand the format
|
|
18
|
+
var examplePlugin = `// Example plugin for Chrxmaticc Copilot
|
|
19
|
+
// Save any .js file in this folder and it auto-loads!
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
name: 'example',
|
|
23
|
+
description: 'An example plugin — try /example',
|
|
24
|
+
category: 'custom',
|
|
25
|
+
|
|
26
|
+
// Called when user types /example
|
|
27
|
+
run: async function(args, context) {
|
|
28
|
+
return 'This is an example plugin! You said: ' + (args || 'nothing');
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
`;
|
|
32
|
+
fs.writeFileSync(path.join(PLUGINS_DIR, 'example.js'), examplePlugin);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
loadAll();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function loadAll() {
|
|
39
|
+
plugins = {};
|
|
40
|
+
pluginCommands = {};
|
|
41
|
+
|
|
42
|
+
if (!fs.existsSync(PLUGINS_DIR)) return;
|
|
43
|
+
|
|
44
|
+
var files = fs.readdirSync(PLUGINS_DIR).filter(function(f) { return f.endsWith('.js'); });
|
|
45
|
+
|
|
46
|
+
files.forEach(function(file) {
|
|
47
|
+
try {
|
|
48
|
+
var pluginPath = path.join(PLUGINS_DIR, file);
|
|
49
|
+
delete require.cache[require.resolve(pluginPath)];
|
|
50
|
+
var plugin = require(pluginPath);
|
|
51
|
+
|
|
52
|
+
if (plugin.name && plugin.run) {
|
|
53
|
+
plugins[plugin.name] = plugin;
|
|
54
|
+
pluginCommands['/' + plugin.name] = plugin;
|
|
55
|
+
console.log(' ' + chalk.green('✓') + ' Plugin loaded: ' + plugin.name + ' — ' + (plugin.description || ''));
|
|
56
|
+
}
|
|
57
|
+
} catch (e) {
|
|
58
|
+
console.log(' ' + chalk.red('✗') + ' Failed to load plugin: ' + file + ' (' + e.message + ')');
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function reload() {
|
|
64
|
+
loadAll();
|
|
65
|
+
return Object.keys(plugins).length;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getPlugin(name) {
|
|
69
|
+
return plugins[name] || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getAllPlugins() {
|
|
73
|
+
return Object.keys(plugins).map(function(key) {
|
|
74
|
+
var p = plugins[key];
|
|
75
|
+
return { name: p.name, description: p.description, category: p.category || 'custom' };
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function runPlugin(name, args, context) {
|
|
80
|
+
var plugin = plugins[name];
|
|
81
|
+
if (!plugin) return null;
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
var result = await plugin.run(args, context);
|
|
85
|
+
return result;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return 'Plugin error: ' + e.message;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function isPluginCommand(command) {
|
|
92
|
+
return command.indexOf('/') === 0 && pluginCommands[command.split(' ')[0]];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getPluginFromCommand(command) {
|
|
96
|
+
var cmdName = command.split(' ')[0].replace('/', '');
|
|
97
|
+
return plugins[cmdName] || null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getPluginDir() {
|
|
101
|
+
return PLUGINS_DIR;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function installPlugin(name, code) {
|
|
105
|
+
var filePath = path.join(PLUGINS_DIR, name + '.js');
|
|
106
|
+
fs.writeFileSync(filePath, code);
|
|
107
|
+
loadAll();
|
|
108
|
+
return { success: true, name: name };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function uninstallPlugin(name) {
|
|
112
|
+
var filePath = path.join(PLUGINS_DIR, name + '.js');
|
|
113
|
+
if (fs.existsSync(filePath)) {
|
|
114
|
+
fs.unlinkSync(filePath);
|
|
115
|
+
loadAll();
|
|
116
|
+
return { success: true, name: name };
|
|
117
|
+
}
|
|
118
|
+
return { success: false, error: 'Plugin not found' };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
init: init,
|
|
123
|
+
reload: reload,
|
|
124
|
+
getPlugin: getPlugin,
|
|
125
|
+
getAllPlugins: getAllPlugins,
|
|
126
|
+
runPlugin: runPlugin,
|
|
127
|
+
isPluginCommand: isPluginCommand,
|
|
128
|
+
getPluginFromCommand: getPluginFromCommand,
|
|
129
|
+
getPluginDir: getPluginDir,
|
|
130
|
+
installPlugin: installPlugin,
|
|
131
|
+
uninstallPlugin: uninstallPlugin
|
|
132
|
+
};
|
package/src/stt.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Chrxmaticc Copilot — Speech-to-Text Module
|
|
2
|
+
// Uses free Google Speech API (no key)
|
|
3
|
+
// Author: Chrxmee-Midnightt
|
|
4
|
+
|
|
5
|
+
var fs = require('fs');
|
|
6
|
+
var path = require('path');
|
|
7
|
+
var { execSync } = require('child_process');
|
|
8
|
+
|
|
9
|
+
function listenFromMic(callback) {
|
|
10
|
+
var tmpFile = path.join('/tmp', 'chrxmaticc_mic_' + Date.now() + '.wav');
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
execSync('arecord -d 5 -f cd -t wav ' + tmpFile + ' 2>/dev/null || sox -d -t wav ' + tmpFile + ' trim 0 5 2>/dev/null || ffmpeg -f avfoundation -i :0 -t 5 ' + tmpFile + ' 2>/dev/null', { timeout: 10000 });
|
|
14
|
+
transcribe(tmpFile, callback);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
if (callback) callback('No microphone found or recording failed', null);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function transcribe(audioPath, callback) {
|
|
21
|
+
var https = require('https');
|
|
22
|
+
var audioData = fs.readFileSync(audioPath);
|
|
23
|
+
var base64 = audioData.toString('base64');
|
|
24
|
+
|
|
25
|
+
var data = JSON.stringify({
|
|
26
|
+
audio: base64,
|
|
27
|
+
encoding: 'LINEAR16',
|
|
28
|
+
sampleRateHertz: 16000,
|
|
29
|
+
languageCode: 'en-US'
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
var options = {
|
|
33
|
+
hostname: 'www.google.com',
|
|
34
|
+
path: '/speech-api/v1/recognize?lang=en-us&client=chromium',
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: {
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
'Content-Length': data.length
|
|
39
|
+
},
|
|
40
|
+
timeout: 10000
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
var req = https.request(options, function(res) {
|
|
44
|
+
var body = '';
|
|
45
|
+
res.on('data', function(chunk) { body = body + chunk; });
|
|
46
|
+
res.on('end', function() {
|
|
47
|
+
try {
|
|
48
|
+
var json = JSON.parse(body);
|
|
49
|
+
var text = json.hypotheses && json.hypotheses[0] && json.hypotheses[0].utterance;
|
|
50
|
+
fs.unlinkSync(audioPath);
|
|
51
|
+
if (callback) callback(null, text || '');
|
|
52
|
+
} catch (e) {
|
|
53
|
+
fs.unlinkSync(audioPath);
|
|
54
|
+
if (callback) callback('Speech recognition failed', null);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
req.on('error', function() {
|
|
60
|
+
fs.unlinkSync(audioPath);
|
|
61
|
+
if (callback) callback('Network error', null);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
req.write(data);
|
|
65
|
+
req.end();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function transcribeFile(audioPath, callback) {
|
|
69
|
+
transcribe(audioPath, callback);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isAvailable() {
|
|
73
|
+
try {
|
|
74
|
+
execSync('which arecord 2>/dev/null || which sox 2>/dev/null || which ffmpeg 2>/dev/null');
|
|
75
|
+
return true;
|
|
76
|
+
} catch (e) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
module.exports = {
|
|
82
|
+
listenFromMic: listenFromMic,
|
|
83
|
+
transcribeFile: transcribeFile,
|
|
84
|
+
isAvailable: isAvailable
|
|
85
|
+
};
|
package/src/tts.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Chrxmaticc Copilot TTS Module
|
|
2
|
+
// Uses Google TTS — free, no API key
|
|
3
|
+
// Author: Chrxmee-Midnightt
|
|
4
|
+
|
|
5
|
+
var https = require('https');
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
var { execSync } = require('child_process');
|
|
9
|
+
|
|
10
|
+
var GOOGLE_TTS_URL = 'https://translate.google.com/translate_tts';
|
|
11
|
+
|
|
12
|
+
function speak(text, lang, callback) {
|
|
13
|
+
lang = lang || 'en';
|
|
14
|
+
var encoded = encodeURIComponent(text.slice(0, 200));
|
|
15
|
+
var url = GOOGLE_TTS_URL + '?ie=UTF-8&client=tw-ob&tl=' + lang + '&q=' + encoded;
|
|
16
|
+
|
|
17
|
+
var tmpFile = path.join('/tmp', 'chrxmaticc_tts_' + Date.now() + '.mp3');
|
|
18
|
+
var file = fs.createWriteStream(tmpFile);
|
|
19
|
+
|
|
20
|
+
https.get(url, function(response) {
|
|
21
|
+
response.pipe(file);
|
|
22
|
+
|
|
23
|
+
file.on('finish', function() {
|
|
24
|
+
file.close();
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
execSync('ffplay -nodisp -autoexit -loglevel quiet ' + tmpFile);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
try {
|
|
30
|
+
execSync('mpg123 -q ' + tmpFile);
|
|
31
|
+
} catch (e2) {
|
|
32
|
+
try {
|
|
33
|
+
execSync('ffplay -nodisp -autoexit -loglevel quiet ' + tmpFile);
|
|
34
|
+
} catch (e3) {
|
|
35
|
+
if (callback) callback(new Error('No audio player found'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fs.unlinkSync(tmpFile);
|
|
42
|
+
if (callback) callback(null);
|
|
43
|
+
});
|
|
44
|
+
}).on('error', function(e) {
|
|
45
|
+
if (callback) callback(e);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function speakToFile(text, outputPath, lang, callback) {
|
|
50
|
+
lang = lang || 'en';
|
|
51
|
+
var encoded = encodeURIComponent(text.slice(0, 200));
|
|
52
|
+
var url = GOOGLE_TTS_URL + '?ie=UTF-8&client=tw-ob&tl=' + lang + '&q=' + encoded;
|
|
53
|
+
|
|
54
|
+
var file = fs.createWriteStream(outputPath);
|
|
55
|
+
|
|
56
|
+
https.get(url, function(response) {
|
|
57
|
+
response.pipe(file);
|
|
58
|
+
|
|
59
|
+
file.on('finish', function() {
|
|
60
|
+
file.close();
|
|
61
|
+
if (callback) callback(null, outputPath);
|
|
62
|
+
});
|
|
63
|
+
}).on('error', function(e) {
|
|
64
|
+
if (callback) callback(e);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isAvailable() {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = { speak: speak, speakToFile: speakToFile, isAvailable: isAvailable };
|
package/src/voice.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
var chalk = require('chalk');
|
|
2
|
+
// Chrxmaticc Copilot — Voice Engine
|
|
3
|
+
// Combines STT (input) + Chat (processing) + TTS (output)
|
|
4
|
+
// Author: Chrxmee-Midnightt
|
|
5
|
+
|
|
6
|
+
var stt = require('./stt');
|
|
7
|
+
var tts = require('./tts');
|
|
8
|
+
var chat = require('./chat');
|
|
9
|
+
var chalk = require('chalk');
|
|
10
|
+
|
|
11
|
+
function voiceChat(rl, callback) {
|
|
12
|
+
console.log('');
|
|
13
|
+
console.log(' ' + chalk.magenta('🎤 Listening... (5 seconds)'));
|
|
14
|
+
console.log('');
|
|
15
|
+
|
|
16
|
+
stt.listenFromMic(function(err, text) {
|
|
17
|
+
if (err || !text) {
|
|
18
|
+
console.log(' ' + chalk.red('✗ ' + (err || 'No speech detected')));
|
|
19
|
+
console.log('');
|
|
20
|
+
if (callback) callback('voice_failed');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(' ' + chalk.cyan('you > ') + text);
|
|
25
|
+
console.log('');
|
|
26
|
+
|
|
27
|
+
chat.getResponse(text).then(function(response) {
|
|
28
|
+
var responseText = typeof response === 'string' ? response : response.text;
|
|
29
|
+
|
|
30
|
+
console.log(' ' + chalk.magenta('chrxmaticc > ') + responseText);
|
|
31
|
+
console.log('');
|
|
32
|
+
|
|
33
|
+
tts.speak(responseText, 'en', function() {
|
|
34
|
+
if (callback) callback('voice_done');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function processVoiceMessage(audioBuffer, userId, callback) {
|
|
41
|
+
var fs = require('fs');
|
|
42
|
+
var path = require('path');
|
|
43
|
+
var tmpFile = path.join('/tmp', 'chrxmaticc_discord_' + userId + '_' + Date.now() + '.wav');
|
|
44
|
+
|
|
45
|
+
fs.writeFileSync(tmpFile, audioBuffer);
|
|
46
|
+
|
|
47
|
+
stt.transcribeFile(tmpFile, function(err, text) {
|
|
48
|
+
if (err || !text) {
|
|
49
|
+
fs.unlinkSync(tmpFile);
|
|
50
|
+
if (callback) callback('voice_failed', null);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
var multiChat = require('./multi-user-chat');
|
|
55
|
+
multiChat.getResponse(text, userId).then(function(response) {
|
|
56
|
+
var responseText = typeof response === 'string' ? response : response.text;
|
|
57
|
+
if (callback) callback(null, { text: responseText, userText: text });
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
voiceChat: voiceChat,
|
|
64
|
+
processVoiceMessage: processVoiceMessage
|
|
65
|
+
};
|