Spaces:
Runtime error
Runtime error
Upload folder using huggingface_hub
Browse files
app.py
CHANGED
|
@@ -38,6 +38,12 @@ async def chat(request: Request):
|
|
| 38 |
messages = body.get("messages", [])
|
| 39 |
client_tools = body.get("tools", [])
|
| 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
# Associer les outils locaux du client et l'outil de recherche web du serveur
|
| 42 |
all_tools = list(client_tools)
|
| 43 |
search_tool_def = {
|
|
@@ -62,9 +68,12 @@ async def chat(request: Request):
|
|
| 62 |
# Boucle d'agent côté serveur pour exécuter search_web de manière transparente
|
| 63 |
while True:
|
| 64 |
response = client.chat_completion(
|
|
|
|
| 65 |
messages=messages,
|
| 66 |
tools=all_tools,
|
| 67 |
-
max_tokens=
|
|
|
|
|
|
|
| 68 |
stream=False
|
| 69 |
)
|
| 70 |
choice = response.choices[0]
|
|
|
|
| 38 |
messages = body.get("messages", [])
|
| 39 |
client_tools = body.get("tools", [])
|
| 40 |
|
| 41 |
+
# dynamic inference parameters
|
| 42 |
+
model = body.get("model", "Qwen/Qwen2.5-Coder-32B-Instruct")
|
| 43 |
+
temperature = body.get("temperature", None)
|
| 44 |
+
top_p = body.get("top_p", None)
|
| 45 |
+
max_tokens = body.get("max_tokens", 2048)
|
| 46 |
+
|
| 47 |
# Associer les outils locaux du client et l'outil de recherche web du serveur
|
| 48 |
all_tools = list(client_tools)
|
| 49 |
search_tool_def = {
|
|
|
|
| 68 |
# Boucle d'agent côté serveur pour exécuter search_web de manière transparente
|
| 69 |
while True:
|
| 70 |
response = client.chat_completion(
|
| 71 |
+
model=model,
|
| 72 |
messages=messages,
|
| 73 |
tools=all_tools,
|
| 74 |
+
max_tokens=max_tokens,
|
| 75 |
+
temperature=temperature,
|
| 76 |
+
top_p=top_p,
|
| 77 |
stream=False
|
| 78 |
)
|
| 79 |
choice = response.choices[0]
|
index.js
CHANGED
|
@@ -26,6 +26,37 @@ marked.setOptions({
|
|
| 26 |
const AUTHOR = "DJAKOUA KWANKAM";
|
| 27 |
const APP_NAME = "Cypher Coder";
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
// Banner ASCII Art pour l'interface de démarrage
|
| 30 |
const BANNER = chalk.cyan.bold(`
|
| 31 |
_____ _---------------+
|
|
@@ -150,10 +181,18 @@ const tools = [
|
|
| 150 |
|
| 151 |
// Outil d'exécution d'API robuste via curl pour contourner les problèmes de socket de Node.js
|
| 152 |
function callApiViaCurl(messages, clientTools) {
|
| 153 |
-
const payload = JSON.stringify({
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 154 |
const escapedPayload = payload.replace(/'/g, "'\\''");
|
| 155 |
const command = `curl -s -X POST -H "Content-Type: application/json" -d '${escapedPayload}' https://theshellmaster-cypher-coder.hf.space/api/chat`;
|
| 156 |
|
|
|
|
| 157 |
const output = execSync(command).toString();
|
| 158 |
try {
|
| 159 |
const responseJson = JSON.parse(output);
|
|
@@ -672,7 +711,6 @@ Le répertoire de travail actuel contient les dossiers et fichiers suivants au p
|
|
| 672 |
Sois précis, concis et direct. Formate tes réponses en Markdown standard.`;
|
| 673 |
}
|
| 674 |
|
| 675 |
-
let chatMessages = [];
|
| 676 |
|
| 677 |
function initChat() {
|
| 678 |
chatMessages = [{"role": "system", "content": getSystemPrompt()}];
|
|
@@ -692,6 +730,8 @@ async function runAgentTurn() {
|
|
| 692 |
chatMessages.push(replyMessage);
|
| 693 |
|
| 694 |
if (replyMessage.content) {
|
|
|
|
|
|
|
| 695 |
console.log(chalk.green(`\n🤖 Cypher : `));
|
| 696 |
// Rendre le Markdown de l'IA avec formatage ANSI coloré
|
| 697 |
console.log(marked(replyMessage.content));
|
|
@@ -725,6 +765,807 @@ async function runAgentTurn() {
|
|
| 725 |
}
|
| 726 |
}
|
| 727 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 728 |
async function askQuestion() {
|
| 729 |
const { userInput } = await inquirer.prompt([
|
| 730 |
{
|
|
@@ -741,40 +1582,16 @@ async function askQuestion() {
|
|
| 741 |
return askQuestion();
|
| 742 |
}
|
| 743 |
|
| 744 |
-
if (text
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
if (text === '/clear') {
|
| 750 |
-
console.clear();
|
| 751 |
-
initChat();
|
| 752 |
-
console.log(BANNER);
|
| 753 |
-
console.log(chalk.green("Discussion réinitialisée et répertoire indexé.\n"));
|
| 754 |
-
return askQuestion();
|
| 755 |
-
}
|
| 756 |
-
|
| 757 |
-
if (text === '/help') {
|
| 758 |
-
console.log(chalk.yellow("\nCommandes disponibles :"));
|
| 759 |
-
console.log(" /help - Affiche ce menu d'aide");
|
| 760 |
-
console.log(" /status - Affiche le dossier actif, le backend et l'index de fichiers");
|
| 761 |
-
console.log(" /clear - Efface l'écran et réinitialise la discussion et le contexte");
|
| 762 |
-
console.log(" /exit - Quitte l'application\n");
|
| 763 |
-
return askQuestion();
|
| 764 |
}
|
| 765 |
|
| 766 |
-
|
| 767 |
-
|
| 768 |
-
console.log(chalk.yellow("\n=== Statut de la Session ==="));
|
| 769 |
-
console.log(` Dossier de travail : ${chalk.cyan(path.resolve("."))}`);
|
| 770 |
-
console.log(` Backend Space : ${chalk.cyan("https://theshellmaster-cypher-coder.hf.space")}`);
|
| 771 |
-
console.log(` Modèle utilisé : ${chalk.cyan("Qwen/Qwen2.5-Coder-32B-Instruct")}`);
|
| 772 |
-
console.log(` Auteur : ${chalk.cyan("DJAKOUA KWANKAM (IUD)")}`);
|
| 773 |
-
console.log(` Fichiers suivis : ${chalk.dim(dirContext)}\n`);
|
| 774 |
-
return askQuestion();
|
| 775 |
-
}
|
| 776 |
|
| 777 |
-
// Ajouter le message utilisateur et démarrer le tour d'agent
|
| 778 |
chatMessages.push({"role": "user", "content": text});
|
| 779 |
await runAgentTurn();
|
| 780 |
|
|
|
|
| 26 |
const AUTHOR = "DJAKOUA KWANKAM";
|
| 27 |
const APP_NAME = "Cypher Coder";
|
| 28 |
|
| 29 |
+
// Global Session State & Config
|
| 30 |
+
let chatMessages = [];
|
| 31 |
+
let lastUserInput = "";
|
| 32 |
+
let lastAssistantResponse = "";
|
| 33 |
+
let commandHistory = [];
|
| 34 |
+
let savedContexts = {};
|
| 35 |
+
let loadedFiles = [];
|
| 36 |
+
let macros = {};
|
| 37 |
+
let logs = [];
|
| 38 |
+
|
| 39 |
+
const sessionConfig = {
|
| 40 |
+
model: "Qwen/Qwen2.5-Coder-32B-Instruct",
|
| 41 |
+
temperature: 0.7,
|
| 42 |
+
top_p: 0.9,
|
| 43 |
+
max_tokens: 2048,
|
| 44 |
+
stream: false,
|
| 45 |
+
sandbox: false,
|
| 46 |
+
verbose: false,
|
| 47 |
+
silent: false,
|
| 48 |
+
color: true,
|
| 49 |
+
theme: "dark",
|
| 50 |
+
format: "md",
|
| 51 |
+
lang: "fr",
|
| 52 |
+
env: {}
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
function addLog(level, message) {
|
| 56 |
+
const logItem = `[${new Date().toISOString()}] [${level}] ${message}`;
|
| 57 |
+
logs.push(logItem);
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
// Banner ASCII Art pour l'interface de démarrage
|
| 61 |
const BANNER = chalk.cyan.bold(`
|
| 62 |
_____ _---------------+
|
|
|
|
| 181 |
|
| 182 |
// Outil d'exécution d'API robuste via curl pour contourner les problèmes de socket de Node.js
|
| 183 |
function callApiViaCurl(messages, clientTools) {
|
| 184 |
+
const payload = JSON.stringify({
|
| 185 |
+
messages,
|
| 186 |
+
tools: clientTools,
|
| 187 |
+
model: sessionConfig.model,
|
| 188 |
+
temperature: sessionConfig.temperature,
|
| 189 |
+
top_p: sessionConfig.top_p,
|
| 190 |
+
max_tokens: sessionConfig.max_tokens
|
| 191 |
+
});
|
| 192 |
const escapedPayload = payload.replace(/'/g, "'\\''");
|
| 193 |
const command = `curl -s -X POST -H "Content-Type: application/json" -d '${escapedPayload}' https://theshellmaster-cypher-coder.hf.space/api/chat`;
|
| 194 |
|
| 195 |
+
addLog("DEBUG", `Envoi payload API vers HF Space: modèle=${sessionConfig.model}, température=${sessionConfig.temperature}`);
|
| 196 |
const output = execSync(command).toString();
|
| 197 |
try {
|
| 198 |
const responseJson = JSON.parse(output);
|
|
|
|
| 711 |
Sois précis, concis et direct. Formate tes réponses en Markdown standard.`;
|
| 712 |
}
|
| 713 |
|
|
|
|
| 714 |
|
| 715 |
function initChat() {
|
| 716 |
chatMessages = [{"role": "system", "content": getSystemPrompt()}];
|
|
|
|
| 730 |
chatMessages.push(replyMessage);
|
| 731 |
|
| 732 |
if (replyMessage.content) {
|
| 733 |
+
lastAssistantResponse = replyMessage.content;
|
| 734 |
+
addLog("INFO", "Réponse de l'assistant enregistrée.");
|
| 735 |
console.log(chalk.green(`\n🤖 Cypher : `));
|
| 736 |
// Rendre le Markdown de l'IA avec formatage ANSI coloré
|
| 737 |
console.log(marked(replyMessage.content));
|
|
|
|
| 765 |
}
|
| 766 |
}
|
| 767 |
|
| 768 |
+
async function handleSlashCommand(text) {
|
| 769 |
+
if (!text.startsWith('/')) {
|
| 770 |
+
return false;
|
| 771 |
+
}
|
| 772 |
+
|
| 773 |
+
const parts = text.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
| 774 |
+
if (parts.length === 0) return true;
|
| 775 |
+
|
| 776 |
+
const commandName = parts[0];
|
| 777 |
+
const rawArgs = parts.slice(1).map(a => a.replace(/^["']|["']$/g, ''));
|
| 778 |
+
|
| 779 |
+
addLog("INFO", `Commande slash reçue: ${text}`);
|
| 780 |
+
commandHistory.push(text);
|
| 781 |
+
|
| 782 |
+
const cleanArgs = [];
|
| 783 |
+
const flags = {};
|
| 784 |
+
for (let i = 0; i < rawArgs.length; i++) {
|
| 785 |
+
if (rawArgs[i].startsWith('--')) {
|
| 786 |
+
const key = rawArgs[i].slice(2);
|
| 787 |
+
if (rawArgs[i+1] && !rawArgs[i+1].startsWith('--')) {
|
| 788 |
+
flags[key] = rawArgs[++i];
|
| 789 |
+
} else {
|
| 790 |
+
flags[key] = true;
|
| 791 |
+
}
|
| 792 |
+
} else {
|
| 793 |
+
cleanArgs.push(rawArgs[i]);
|
| 794 |
+
}
|
| 795 |
+
}
|
| 796 |
+
|
| 797 |
+
switch (commandName.toLowerCase()) {
|
| 798 |
+
// --- 1. Contrôle de session
|
| 799 |
+
case '/help':
|
| 800 |
+
console.log(chalk.cyan.bold("\n📚 CYPHER CODER CLI - COMMANDES DISPONIBLES :"));
|
| 801 |
+
|
| 802 |
+
console.log(chalk.yellow("\n🎛️ Session :"));
|
| 803 |
+
console.log(" /help - Affiche ce menu d'aide");
|
| 804 |
+
console.log(" /exit, /quit - Quitte proprement l'agent");
|
| 805 |
+
console.log(" /clear - Efface l'écran");
|
| 806 |
+
console.log(" /reset - Réinitialise la discussion et l'historique");
|
| 807 |
+
console.log(" /restart - Redémarre proprement la session");
|
| 808 |
+
console.log(" /version - Affiche la version actuelle");
|
| 809 |
+
console.log(" /about - Infos sur le projet");
|
| 810 |
+
console.log(" /status - Affiche le statut complet");
|
| 811 |
+
|
| 812 |
+
console.log(chalk.yellow("\n💬 Mémoire et Contexte :"));
|
| 813 |
+
console.log(" /context - Affiche les fichiers chargés en contexte");
|
| 814 |
+
console.log(" /context clear - Efface le contexte de fichiers");
|
| 815 |
+
console.log(" /context save <nom> - Sauvegarde la session actuelle");
|
| 816 |
+
console.log(" /context load <nom> - Charge une session sauvegardée");
|
| 817 |
+
console.log(" /context list - Liste les sessions sauvegardées");
|
| 818 |
+
console.log(" /memory - Affiche la mémoire système + messages");
|
| 819 |
+
console.log(" /memory clear - Efface les messages d'historique");
|
| 820 |
+
console.log(" /tokens - Affiche les statistiques de tokens");
|
| 821 |
+
|
| 822 |
+
console.log(chalk.yellow("\n📜 Historique :"));
|
| 823 |
+
console.log(" /history - Affiche tout l'historique");
|
| 824 |
+
console.log(" /history clear - Efface l'historique enregistré");
|
| 825 |
+
console.log(" /history save <fichier> - Exporte l'historique dans un fichier");
|
| 826 |
+
console.log(" /history load <fichier> - Importe un historique");
|
| 827 |
+
console.log(" /history search <terme> - Cherche dans l'historique");
|
| 828 |
+
console.log(" /last - Affiche la dernière réponse de l'agent");
|
| 829 |
+
console.log(" /redo - Relance la dernière requête");
|
| 830 |
+
console.log(" /undo - Annule la dernière interaction");
|
| 831 |
+
|
| 832 |
+
console.log(chalk.yellow("\n🤖 Modèle et Configuration :"));
|
| 833 |
+
console.log(" /model - Affiche le modèle utilisé");
|
| 834 |
+
console.log(" /model list - Liste les modèles supportés");
|
| 835 |
+
console.log(" /model set <nom> - Change de modèle");
|
| 836 |
+
console.log(" /model info - Affiche les infos du modèle");
|
| 837 |
+
console.log(" /temperature <valeur> - Ajuste la température (0.0 - 1.0)");
|
| 838 |
+
console.log(" /top_p <valeur> - Ajuste le top_p");
|
| 839 |
+
console.log(" /max_tokens <valeur> - Ajuste la limite de tokens");
|
| 840 |
+
console.log(" /system - Affiche le prompt système");
|
| 841 |
+
console.log(" /system set <prompt> - Modifie le prompt système");
|
| 842 |
+
console.log(" /system reset - Réinitialise le prompt système");
|
| 843 |
+
console.log(" /stream <on|off> - Active/désactive le streaming");
|
| 844 |
+
|
| 845 |
+
console.log(chalk.yellow("\n📁 Fichiers :"));
|
| 846 |
+
console.log(" /file load <chemin> - Charge le fichier dans le contexte");
|
| 847 |
+
console.log(" /file read <chemin> - Lit et affiche un fichier");
|
| 848 |
+
console.log(" /file write <chemin> - Écrit la dernière réponse dans un fichier");
|
| 849 |
+
console.log(" /file append <chemin> - Ajoute la dernière réponse à un fichier");
|
| 850 |
+
console.log(" /file list - Liste les fichiers chargés");
|
| 851 |
+
console.log(" /file clear - Vide le contexte de fichiers");
|
| 852 |
+
console.log(" /file diff <f1> <f2> - Compare deux fichiers");
|
| 853 |
+
console.log(" /upload <chemin> - Simule l'envoi d'un fichier");
|
| 854 |
+
console.log(" /download <nom> - Télécharge un fichier");
|
| 855 |
+
|
| 856 |
+
console.log(chalk.yellow("\n⚡ Code et Commandes :"));
|
| 857 |
+
console.log(" /run - Exécute le dernier bloc de code");
|
| 858 |
+
console.log(" /run <lang> <code> - Exécute le code fourni");
|
| 859 |
+
console.log(" /exec <commande> - Lance une commande système");
|
| 860 |
+
console.log(" /shell - Lance un terminal interactif");
|
| 861 |
+
console.log(" /repl <lang> - Lance un REPL (ex: node, python)");
|
| 862 |
+
console.log(" /eval <expression> - Évalue une expression mathématique");
|
| 863 |
+
console.log(" /sandbox <on|off> - Active/désactive l'isolation");
|
| 864 |
+
console.log(" /output - Affiche la dernière sortie");
|
| 865 |
+
console.log(" /output clear - Efface la dernière sortie");
|
| 866 |
+
|
| 867 |
+
console.log(chalk.yellow("\n🔌 Outils et Recherche :"));
|
| 868 |
+
console.log(" /tools - Liste les outils activés");
|
| 869 |
+
console.log(" /tool info <nom> - Affiche la description d'un outil");
|
| 870 |
+
console.log(" /tool enable/disable <n> - Active/désactive un outil");
|
| 871 |
+
console.log(" /plugin list/install/rm - Gère les plugins");
|
| 872 |
+
console.log(" /web search <requête> - Recherche en ligne");
|
| 873 |
+
console.log(" /web fetch <url> - Récupère le contenu d'une URL");
|
| 874 |
+
|
| 875 |
+
console.log(chalk.yellow("\n🎨 Thème et Affichage :"));
|
| 876 |
+
console.log(" /theme <dark|light> - Change le thème");
|
| 877 |
+
console.log(" /theme list - Liste les thèmes");
|
| 878 |
+
console.log(" /format <md|plain|json> - Format des réponses");
|
| 879 |
+
console.log(" /wrap <on|off> - Retour à la ligne automatique");
|
| 880 |
+
console.log(" /verbose <on|off> - Mode verbeux");
|
| 881 |
+
console.log(" /silent <on|off> - Mode silencieux");
|
| 882 |
+
console.log(" /color <on|off> - Colorisation syntaxique");
|
| 883 |
+
console.log(" /lang <fr|en> - Change la langue");
|
| 884 |
+
|
| 885 |
+
console.log(chalk.yellow("\n🔐 Configuration et Variable d'env :"));
|
| 886 |
+
console.log(" /config - Affiche la configuration");
|
| 887 |
+
console.log(" /config set <key> <val> - Modifie la configuration");
|
| 888 |
+
console.log(" /config reset - Réinitialise la configuration");
|
| 889 |
+
console.log(" /env list - Liste les variables d'env");
|
| 890 |
+
console.log(" /env set <VAR> <val> - Définit une variable d'env");
|
| 891 |
+
console.log(" /api key show/set/clear - Gère les clés d'API");
|
| 892 |
+
|
| 893 |
+
console.log(chalk.yellow("\n📊 Monitoring et Debug :"));
|
| 894 |
+
console.log(" /debug <on|off> - Active le mode debug");
|
| 895 |
+
console.log(" /log - Affiche les logs");
|
| 896 |
+
console.log(" /log clear/save - Efface ou enregistre les logs");
|
| 897 |
+
console.log(" /benchmark - Teste la latence API");
|
| 898 |
+
console.log(" /ping - Teste la connexion réseau");
|
| 899 |
+
console.log(" /stats - Statistiques de session");
|
| 900 |
+
console.log(" /trace - Trace des appels");
|
| 901 |
+
console.log(" /inspect <var> - Inspecte la configuration interne");
|
| 902 |
+
|
| 903 |
+
console.log(chalk.yellow("\n🔁 Automatisation :"));
|
| 904 |
+
console.log(" /macro save/run/list/del - Gère les macros");
|
| 905 |
+
console.log(" /pipe <cmd1> | <cmd2> - Chaîne deux commandes");
|
| 906 |
+
console.log(" /loop <n> <commande> - Répète une commande");
|
| 907 |
+
console.log(" /schedule <cron> <cmd> - Planifie une tâche");
|
| 908 |
+
console.log(" /watch <cmd> - Surveille les fichiers");
|
| 909 |
+
console.log(" /batch <fichier> - Exécute des commandes en lot\n");
|
| 910 |
+
break;
|
| 911 |
+
|
| 912 |
+
case '/exit':
|
| 913 |
+
case '/quit':
|
| 914 |
+
console.log(chalk.gray("Fermeture de Cypher Coder. À bientôt !"));
|
| 915 |
+
process.exit(0);
|
| 916 |
+
|
| 917 |
+
case '/clear':
|
| 918 |
+
console.clear();
|
| 919 |
+
console.log(BANNER);
|
| 920 |
+
console.log(chalk.green("Écran nettoyé.\n"));
|
| 921 |
+
break;
|
| 922 |
+
|
| 923 |
+
case '/reset':
|
| 924 |
+
initChat();
|
| 925 |
+
commandHistory = [];
|
| 926 |
+
loadedFiles = [];
|
| 927 |
+
console.log(chalk.green("Session réinitialisée. Historique et contexte effacés.\n"));
|
| 928 |
+
break;
|
| 929 |
+
|
| 930 |
+
case '/restart':
|
| 931 |
+
console.log(chalk.yellow("Redémarrage de l'agent en cours..."));
|
| 932 |
+
initChat();
|
| 933 |
+
console.clear();
|
| 934 |
+
console.log(BANNER);
|
| 935 |
+
console.log(chalk.green("Cypher Coder a redémarré avec succès.\n"));
|
| 936 |
+
break;
|
| 937 |
+
|
| 938 |
+
case '/version':
|
| 939 |
+
console.log(chalk.cyan(`Version de Cypher Coder: 1.0.0 (Mode Hybride local/Space)`));
|
| 940 |
+
break;
|
| 941 |
+
|
| 942 |
+
case '/about':
|
| 943 |
+
console.log(chalk.cyan(`\n=== À propos de Cypher Coder ===`));
|
| 944 |
+
console.log(`Nom : ${APP_NAME}`);
|
| 945 |
+
console.log(`Créateur : ${AUTHOR} (Étudiant IUD)`);
|
| 946 |
+
console.log(`Description: Assistant IA autonome de codage local et réseau.`);
|
| 947 |
+
console.log(`Modèle : Qwen/Qwen2.5-Coder-32B-Instruct`);
|
| 948 |
+
console.log(`Réseau : FastAPI + Gradio (Docker Space HF)\n`);
|
| 949 |
+
break;
|
| 950 |
+
|
| 951 |
+
case '/status':
|
| 952 |
+
const dirContext = getCurrentDirectoryContext();
|
| 953 |
+
console.log(chalk.yellow("\n=== Statut de la Session ==="));
|
| 954 |
+
console.log(` Dossier de travail : ${chalk.cyan(path.resolve("."))}`);
|
| 955 |
+
console.log(` Backend Space : ${chalk.cyan("https://theshellmaster-cypher-coder.hf.space")}`);
|
| 956 |
+
console.log(` Modèle utilisé : ${chalk.cyan(sessionConfig.model)}`);
|
| 957 |
+
console.log(` Température : ${chalk.cyan(sessionConfig.temperature)}`);
|
| 958 |
+
console.log(` Max Tokens : ${chalk.cyan(sessionConfig.max_tokens)}`);
|
| 959 |
+
console.log(` Auteur : ${chalk.cyan(AUTHOR)}`);
|
| 960 |
+
console.log(` Fichiers suivis : ${chalk.dim(dirContext)}\n`);
|
| 961 |
+
break;
|
| 962 |
+
|
| 963 |
+
// --- 2. Gestion du contexte & mémoire
|
| 964 |
+
case '/context':
|
| 965 |
+
if (cleanArgs[0] === 'clear') {
|
| 966 |
+
loadedFiles = [];
|
| 967 |
+
console.log(chalk.green("Contexte de fichiers vidé."));
|
| 968 |
+
} else if (cleanArgs[0] === 'save') {
|
| 969 |
+
const name = cleanArgs[1];
|
| 970 |
+
if (!name) {
|
| 971 |
+
console.log(chalk.red("Erreur: Spécifiez un nom. Exemple: /context save ma_session"));
|
| 972 |
+
} else {
|
| 973 |
+
savedContexts[name] = JSON.stringify(chatMessages);
|
| 974 |
+
console.log(chalk.green(`Contexte sauvegardé sous le nom '${name}'.`));
|
| 975 |
+
}
|
| 976 |
+
} else if (cleanArgs[0] === 'load') {
|
| 977 |
+
const name = cleanArgs[1];
|
| 978 |
+
if (!name || !savedContexts[name]) {
|
| 979 |
+
console.log(chalk.red(`Erreur: Contexte '${name}' introuvable.`));
|
| 980 |
+
} else {
|
| 981 |
+
chatMessages = JSON.parse(savedContexts[name]);
|
| 982 |
+
console.log(chalk.green(`Contexte '${name}' restauré avec succès.`));
|
| 983 |
+
}
|
| 984 |
+
} else if (cleanArgs[0] === 'list') {
|
| 985 |
+
console.log(chalk.yellow("Contextes sauvegardés :"), Object.keys(savedContexts));
|
| 986 |
+
} else {
|
| 987 |
+
console.log(chalk.yellow("Fichiers chargés en contexte local :"));
|
| 988 |
+
if (loadedFiles.length === 0) console.log(" Aucun fichier chargé.");
|
| 989 |
+
loadedFiles.forEach(f => console.log(` - ${f}`));
|
| 990 |
+
}
|
| 991 |
+
break;
|
| 992 |
+
|
| 993 |
+
case '/memory':
|
| 994 |
+
if (cleanArgs[0] === 'clear') {
|
| 995 |
+
initChat();
|
| 996 |
+
console.log(chalk.green("Mémoire système réinitialisée."));
|
| 997 |
+
} else {
|
| 998 |
+
console.log(chalk.yellow("\n=== Mémoire de session active ==="));
|
| 999 |
+
console.log(`Nombre de messages stockés : ${chatMessages.length}`);
|
| 1000 |
+
console.log("System Prompt actif :");
|
| 1001 |
+
console.log(chalk.dim(chatMessages[0]?.content || "Aucun"));
|
| 1002 |
+
console.log("===================================\n");
|
| 1003 |
+
}
|
| 1004 |
+
break;
|
| 1005 |
+
|
| 1006 |
+
case '/tokens':
|
| 1007 |
+
const textLength = JSON.stringify(chatMessages).length;
|
| 1008 |
+
const estTokens = Math.round(textLength / 4);
|
| 1009 |
+
console.log(chalk.cyan(`Statistiques de tokens (estimations) :`));
|
| 1010 |
+
console.log(` Utilisés (contexte actuel) : ~${estTokens} tokens`);
|
| 1011 |
+
console.log(` Max configuré par réponse : ${sessionConfig.max_tokens} tokens`);
|
| 1012 |
+
break;
|
| 1013 |
+
|
| 1014 |
+
// --- 3. Historique
|
| 1015 |
+
case '/history':
|
| 1016 |
+
if (cleanArgs[0] === 'clear') {
|
| 1017 |
+
commandHistory = [];
|
| 1018 |
+
console.log(chalk.green("Historique des commandes vidé."));
|
| 1019 |
+
} else if (cleanArgs[0] === 'save') {
|
| 1020 |
+
const file = cleanArgs[1] || 'history_export.json';
|
| 1021 |
+
fs.writeFileSync(file, JSON.stringify(commandHistory, null, 2), 'utf8');
|
| 1022 |
+
console.log(chalk.green(`Historique exporté dans : ${file}`));
|
| 1023 |
+
} else if (cleanArgs[0] === 'load') {
|
| 1024 |
+
const file = cleanArgs[1];
|
| 1025 |
+
if (file && fs.existsSync(file)) {
|
| 1026 |
+
commandHistory = JSON.parse(fs.readFileSync(file, 'utf8'));
|
| 1027 |
+
console.log(chalk.green(`Historique importé depuis ${file}.`));
|
| 1028 |
+
} else {
|
| 1029 |
+
console.log(chalk.red("Fichier introuvable."));
|
| 1030 |
+
}
|
| 1031 |
+
} else if (cleanArgs[0] === 'search') {
|
| 1032 |
+
const query = cleanArgs.slice(1).join(' ').toLowerCase();
|
| 1033 |
+
const matches = commandHistory.filter(h => h.toLowerCase().includes(query));
|
| 1034 |
+
console.log(chalk.yellow(`Correspondances trouvées (${matches.length}) :`));
|
| 1035 |
+
matches.forEach(m => console.log(` ${m}`));
|
| 1036 |
+
} else {
|
| 1037 |
+
console.log(chalk.yellow("\n=== Historique des commandes utilisateur ==="));
|
| 1038 |
+
commandHistory.forEach((c, idx) => console.log(` ${idx + 1}. ${c}`));
|
| 1039 |
+
console.log("=============================================\n");
|
| 1040 |
+
}
|
| 1041 |
+
break;
|
| 1042 |
+
|
| 1043 |
+
case '/last':
|
| 1044 |
+
if (!lastAssistantResponse) {
|
| 1045 |
+
console.log(chalk.yellow("Aucune réponse précédente disponible."));
|
| 1046 |
+
} else {
|
| 1047 |
+
console.log(chalk.green("\n🤖 Dernière réponse de Cypher :"));
|
| 1048 |
+
console.log(marked(lastAssistantResponse));
|
| 1049 |
+
}
|
| 1050 |
+
break;
|
| 1051 |
+
|
| 1052 |
+
case '/redo':
|
| 1053 |
+
let lastUserText = "";
|
| 1054 |
+
for (let i = chatMessages.length - 1; i >= 0; i--) {
|
| 1055 |
+
if (chatMessages[i].role === 'user' && !chatMessages[i].content.startsWith('/')) {
|
| 1056 |
+
lastUserText = chatMessages[i].content;
|
| 1057 |
+
break;
|
| 1058 |
+
}
|
| 1059 |
+
}
|
| 1060 |
+
if (lastUserText) {
|
| 1061 |
+
console.log(chalk.cyan(`Relance de la requête : "${lastUserText}"`));
|
| 1062 |
+
chatMessages.push({"role": "user", "content": lastUserText});
|
| 1063 |
+
await runAgentTurn();
|
| 1064 |
+
} else {
|
| 1065 |
+
console.log(chalk.yellow("Aucune requête textuelle trouvée à relancer."));
|
| 1066 |
+
}
|
| 1067 |
+
break;
|
| 1068 |
+
|
| 1069 |
+
case '/undo':
|
| 1070 |
+
if (chatMessages.length > 2) {
|
| 1071 |
+
chatMessages.pop();
|
| 1072 |
+
chatMessages.pop();
|
| 1073 |
+
console.log(chalk.green("Dernière interaction utilisateur/assistant annulée du contexte."));
|
| 1074 |
+
} else {
|
| 1075 |
+
console.log(chalk.yellow("Rien à annuler."));
|
| 1076 |
+
}
|
| 1077 |
+
break;
|
| 1078 |
+
|
| 1079 |
+
// --- 4. Gestion du modèle LLM
|
| 1080 |
+
case '/model':
|
| 1081 |
+
if (cleanArgs[0] === 'list') {
|
| 1082 |
+
console.log(chalk.cyan("Modèles disponibles via Hugging Face Inference :"));
|
| 1083 |
+
console.log(" - Qwen/Qwen2.5-Coder-32B-Instruct (Recommandé - Actif par défaut)");
|
| 1084 |
+
console.log(" - meta-llama/Llama-3.3-70B-Instruct");
|
| 1085 |
+
console.log(" - deepseek-ai/DeepSeek-Coder-V2-Instruct");
|
| 1086 |
+
} else if (cleanArgs[0] === 'set') {
|
| 1087 |
+
const newModel = cleanArgs[1];
|
| 1088 |
+
if (!newModel) {
|
| 1089 |
+
console.log(chalk.red("Usage: /model set <nom_du_modèle>"));
|
| 1090 |
+
} else {
|
| 1091 |
+
sessionConfig.model = newModel;
|
| 1092 |
+
console.log(chalk.green(`Modèle modifié vers : ${newModel}`));
|
| 1093 |
+
}
|
| 1094 |
+
} else if (cleanArgs[0] === 'info') {
|
| 1095 |
+
console.log(chalk.cyan(`\n=== Infos sur le modèle actif ===`));
|
| 1096 |
+
console.log(`Nom: ${sessionConfig.model}`);
|
| 1097 |
+
console.log(`Type: Coder/Instruct LLM`);
|
| 1098 |
+
console.log(`Capacités: Génération de code, Tool calling, Recherche web`);
|
| 1099 |
+
console.log(`Limites recommandées: 2048 tokens max par génération.`);
|
| 1100 |
+
} else {
|
| 1101 |
+
console.log(chalk.cyan(`Modèle actif : ${sessionConfig.model}`));
|
| 1102 |
+
}
|
| 1103 |
+
break;
|
| 1104 |
+
|
| 1105 |
+
case '/temperature':
|
| 1106 |
+
const tempVal = parseFloat(cleanArgs[0]);
|
| 1107 |
+
if (isNaN(tempVal) || tempVal < 0 || tempVal > 1) {
|
| 1108 |
+
console.log(chalk.red("Usage: /temperature <valeur entre 0.0 et 1.0> (actuelle: " + sessionConfig.temperature + ")"));
|
| 1109 |
+
} else {
|
| 1110 |
+
sessionConfig.temperature = tempVal;
|
| 1111 |
+
console.log(chalk.green(`Température mise à jour : ${tempVal}`));
|
| 1112 |
+
}
|
| 1113 |
+
break;
|
| 1114 |
+
|
| 1115 |
+
case '/top_p':
|
| 1116 |
+
const topPVal = parseFloat(cleanArgs[0]);
|
| 1117 |
+
if (isNaN(topPVal) || topPVal < 0 || topPVal > 1) {
|
| 1118 |
+
console.log(chalk.red("Usage: /top_p <valeur entre 0.0 et 1.0> (actuel: " + sessionConfig.top_p + ")"));
|
| 1119 |
+
} else {
|
| 1120 |
+
sessionConfig.top_p = topPVal;
|
| 1121 |
+
console.log(chalk.green(`Top_p mis à jour : ${topPVal}`));
|
| 1122 |
+
}
|
| 1123 |
+
break;
|
| 1124 |
+
|
| 1125 |
+
case '/max_tokens':
|
| 1126 |
+
const maxT = parseInt(cleanArgs[0], 10);
|
| 1127 |
+
if (isNaN(maxT) || maxT <= 0) {
|
| 1128 |
+
console.log(chalk.red("Usage: /max_tokens <nombre> (actuel: " + sessionConfig.max_tokens + ")"));
|
| 1129 |
+
} else {
|
| 1130 |
+
sessionConfig.max_tokens = maxT;
|
| 1131 |
+
console.log(chalk.green(`Max tokens mis à jour : ${maxT}`));
|
| 1132 |
+
}
|
| 1133 |
+
break;
|
| 1134 |
+
|
| 1135 |
+
case '/system':
|
| 1136 |
+
if (cleanArgs[0] === 'set') {
|
| 1137 |
+
const newSys = cleanArgs.slice(1).join(' ');
|
| 1138 |
+
chatMessages[0] = { role: 'system', content: newSys };
|
| 1139 |
+
console.log(chalk.green("Prompt système modifié."));
|
| 1140 |
+
} else if (cleanArgs[0] === 'reset') {
|
| 1141 |
+
chatMessages[0] = { role: 'system', content: getSystemPrompt() };
|
| 1142 |
+
console.log(chalk.green("Prompt système réinitialisé aux valeurs par défaut."));
|
| 1143 |
+
} else {
|
| 1144 |
+
console.log(chalk.cyan("Prompt système actif :"));
|
| 1145 |
+
console.log(chalk.dim(chatMessages[0]?.content));
|
| 1146 |
+
}
|
| 1147 |
+
break;
|
| 1148 |
+
|
| 1149 |
+
case '/stream':
|
| 1150 |
+
if (cleanArgs[0] === 'on') {
|
| 1151 |
+
sessionConfig.stream = true;
|
| 1152 |
+
console.log(chalk.green("Streaming activé (simulé)."));
|
| 1153 |
+
} else {
|
| 1154 |
+
sessionConfig.stream = false;
|
| 1155 |
+
console.log(chalk.green("Streaming désactivé."));
|
| 1156 |
+
}
|
| 1157 |
+
break;
|
| 1158 |
+
|
| 1159 |
+
// --- 5. Gestion de fichiers
|
| 1160 |
+
case '/file':
|
| 1161 |
+
if (cleanArgs[0] === 'load') {
|
| 1162 |
+
const fpath = cleanArgs[1];
|
| 1163 |
+
if (fpath && fs.existsSync(fpath)) {
|
| 1164 |
+
loadedFiles.push(path.resolve(fpath));
|
| 1165 |
+
console.log(chalk.green(`Fichier chargé dans le contexte : ${fpath}`));
|
| 1166 |
+
} else {
|
| 1167 |
+
console.log(chalk.red("Fichier introuvable."));
|
| 1168 |
+
}
|
| 1169 |
+
} else if (cleanArgs[0] === 'read') {
|
| 1170 |
+
const fpath = cleanArgs[1];
|
| 1171 |
+
if (fpath && fs.existsSync(fpath)) {
|
| 1172 |
+
console.log(chalk.cyan(`Contenu de ${fpath} :`));
|
| 1173 |
+
console.log(fs.readFileSync(fpath, 'utf8'));
|
| 1174 |
+
} else {
|
| 1175 |
+
console.log(chalk.red("Fichier introuvable."));
|
| 1176 |
+
}
|
| 1177 |
+
} else if (cleanArgs[0] === 'write') {
|
| 1178 |
+
const fpath = cleanArgs[1];
|
| 1179 |
+
if (!fpath) {
|
| 1180 |
+
console.log(chalk.red("Usage: /file write <chemin>"));
|
| 1181 |
+
} else if (!lastAssistantResponse) {
|
| 1182 |
+
console.log(chalk.red("Aucune réponse disponible à enregistrer."));
|
| 1183 |
+
} else {
|
| 1184 |
+
fs.writeFileSync(fpath, lastAssistantResponse, 'utf8');
|
| 1185 |
+
console.log(chalk.green(`Dernière réponse enregistrée dans ${fpath}`));
|
| 1186 |
+
}
|
| 1187 |
+
} else if (cleanArgs[0] === 'append') {
|
| 1188 |
+
const fpath = cleanArgs[1];
|
| 1189 |
+
if (!fpath) {
|
| 1190 |
+
console.log(chalk.red("Usage: /file append <chemin>"));
|
| 1191 |
+
} else if (!lastAssistantResponse) {
|
| 1192 |
+
console.log(chalk.red("Aucune réponse disponible à enregistrer."));
|
| 1193 |
+
} else {
|
| 1194 |
+
fs.appendFileSync(fpath, "\n" + lastAssistantResponse, 'utf8');
|
| 1195 |
+
console.log(chalk.green(`Dernière réponse ajoutée à la fin de ${fpath}`));
|
| 1196 |
+
}
|
| 1197 |
+
} else if (cleanArgs[0] === 'list') {
|
| 1198 |
+
console.log(chalk.yellow("Fichiers suivis :"), loadedFiles);
|
| 1199 |
+
} else if (cleanArgs[0] === 'clear') {
|
| 1200 |
+
loadedFiles = [];
|
| 1201 |
+
console.log(chalk.green("Fichiers déchargés du contexte."));
|
| 1202 |
+
} else if (cleanArgs[0] === 'diff') {
|
| 1203 |
+
const f1 = cleanArgs[1];
|
| 1204 |
+
const f2 = cleanArgs[2];
|
| 1205 |
+
if (f1 && f2 && fs.existsSync(f1) && fs.existsSync(f2)) {
|
| 1206 |
+
console.log(chalk.yellow(`--- Comparaison de ${f1} et ${f2} ---`));
|
| 1207 |
+
try {
|
| 1208 |
+
const out = execSync(`diff -u ${f1} ${f2}`).toString();
|
| 1209 |
+
console.log(out || "Aucune différence.");
|
| 1210 |
+
} catch (e) {
|
| 1211 |
+
console.log(e.stdout ? e.stdout.toString() : e.message);
|
| 1212 |
+
}
|
| 1213 |
+
} else {
|
| 1214 |
+
console.log(chalk.red("Erreur: Spécifiez deux fichiers valides."));
|
| 1215 |
+
}
|
| 1216 |
+
}
|
| 1217 |
+
break;
|
| 1218 |
+
|
| 1219 |
+
case '/upload':
|
| 1220 |
+
console.log(chalk.green(`Fichier ${cleanArgs[0]} simulé comme uploadé.`));
|
| 1221 |
+
break;
|
| 1222 |
+
case '/download':
|
| 1223 |
+
console.log(chalk.green(`Fichier ${cleanArgs[0]} simulé comme téléchargé.`));
|
| 1224 |
+
break;
|
| 1225 |
+
|
| 1226 |
+
// --- 6. Exécution de code
|
| 1227 |
+
case '/run':
|
| 1228 |
+
if (cleanArgs.length === 0) {
|
| 1229 |
+
if (!lastAssistantResponse) {
|
| 1230 |
+
console.log(chalk.red("Aucun code généré précédemment."));
|
| 1231 |
+
} else {
|
| 1232 |
+
const blockRegex = /```(javascript|js|python|py|bash|sh)?\n([\s\S]*?)```/;
|
| 1233 |
+
const match = lastAssistantResponse.match(blockRegex);
|
| 1234 |
+
if (match) {
|
| 1235 |
+
const lang = match[1] || 'js';
|
| 1236 |
+
const code = match[2];
|
| 1237 |
+
console.log(chalk.yellow(`Exécution du bloc de code détecté (${lang})...`));
|
| 1238 |
+
await executeLocalCode(lang, code);
|
| 1239 |
+
} else {
|
| 1240 |
+
console.log(chalk.red("Aucun bloc de code markdown trouvé."));
|
| 1241 |
+
}
|
| 1242 |
+
}
|
| 1243 |
+
} else {
|
| 1244 |
+
const lang = cleanArgs[0];
|
| 1245 |
+
const code = cleanArgs.slice(1).join(' ');
|
| 1246 |
+
await executeLocalCode(lang, code);
|
| 1247 |
+
}
|
| 1248 |
+
break;
|
| 1249 |
+
|
| 1250 |
+
case '/exec':
|
| 1251 |
+
const cmd = cleanArgs.join(' ');
|
| 1252 |
+
if (!cmd) {
|
| 1253 |
+
console.log(chalk.red("Spécifiez une commande à exécuter."));
|
| 1254 |
+
} else {
|
| 1255 |
+
console.log(chalk.cyan(`Exécution de la commande : ${cmd}`));
|
| 1256 |
+
await handleToolExecution('run_command', { command: cmd });
|
| 1257 |
+
}
|
| 1258 |
+
break;
|
| 1259 |
+
|
| 1260 |
+
case '/shell':
|
| 1261 |
+
console.log(chalk.yellow("Lancement du terminal interactif (tapez 'exit' pour quitter le sous-shell)..."));
|
| 1262 |
+
try {
|
| 1263 |
+
execSync('bash', { stdio: 'inherit' });
|
| 1264 |
+
} catch (e) {}
|
| 1265 |
+
break;
|
| 1266 |
+
|
| 1267 |
+
case '/repl':
|
| 1268 |
+
const rlang = cleanArgs[0] || 'node';
|
| 1269 |
+
console.log(chalk.yellow(`Lancement du REPL ${rlang}...`));
|
| 1270 |
+
try {
|
| 1271 |
+
execSync(rlang, { stdio: 'inherit' });
|
| 1272 |
+
} catch (e) {}
|
| 1273 |
+
break;
|
| 1274 |
+
|
| 1275 |
+
case '/eval':
|
| 1276 |
+
const expr = cleanArgs.join(' ');
|
| 1277 |
+
try {
|
| 1278 |
+
const res = eval(expr);
|
| 1279 |
+
console.log(chalk.green(`Résultat : ${res}`));
|
| 1280 |
+
} catch (e) {
|
| 1281 |
+
console.log(chalk.red(`Erreur d'évaluation : ${e.message}`));
|
| 1282 |
+
}
|
| 1283 |
+
break;
|
| 1284 |
+
|
| 1285 |
+
case '/sandbox':
|
| 1286 |
+
if (cleanArgs[0] === 'on') {
|
| 1287 |
+
sessionConfig.sandbox = true;
|
| 1288 |
+
console.log(chalk.green("Bac à sable activé (simulé)."));
|
| 1289 |
+
} else {
|
| 1290 |
+
sessionConfig.sandbox = false;
|
| 1291 |
+
console.log(chalk.green("Bac à sable désactivé."));
|
| 1292 |
+
}
|
| 1293 |
+
break;
|
| 1294 |
+
|
| 1295 |
+
case '/output':
|
| 1296 |
+
if (cleanArgs[0] === 'clear') {
|
| 1297 |
+
console.log(chalk.green("Sortie nettoyée."));
|
| 1298 |
+
} else {
|
| 1299 |
+
console.log(chalk.gray("Aucune sortie récente enregistrée en dehors du terminal."));
|
| 1300 |
+
}
|
| 1301 |
+
break;
|
| 1302 |
+
|
| 1303 |
+
// --- 7. Plugins & outils
|
| 1304 |
+
case '/tools':
|
| 1305 |
+
console.log(chalk.cyan("Outils d'interaction locaux disponibles :"));
|
| 1306 |
+
tools.forEach(t => console.log(` - ${t.function.name} : ${t.function.description}`));
|
| 1307 |
+
break;
|
| 1308 |
+
|
| 1309 |
+
case '/tool':
|
| 1310 |
+
if (cleanArgs[0] === 'info') {
|
| 1311 |
+
const name = cleanArgs[1];
|
| 1312 |
+
const tool = tools.find(t => t.function.name === name);
|
| 1313 |
+
if (tool) {
|
| 1314 |
+
console.log(chalk.cyan(`Outil [${name}] :`), tool.function.description);
|
| 1315 |
+
} else {
|
| 1316 |
+
console.log(chalk.red("Outil introuvable."));
|
| 1317 |
+
}
|
| 1318 |
+
} else {
|
| 1319 |
+
console.log(chalk.yellow("Les outils fondamentaux de Cypher Coder sont activés par défaut pour assurer son autonomie."));
|
| 1320 |
+
}
|
| 1321 |
+
break;
|
| 1322 |
+
|
| 1323 |
+
case '/plugin':
|
| 1324 |
+
console.log(chalk.cyan("Aucun plugin externe installé."));
|
| 1325 |
+
break;
|
| 1326 |
+
|
| 1327 |
+
case '/web':
|
| 1328 |
+
if (cleanArgs[0] === 'search') {
|
| 1329 |
+
const q = cleanArgs.slice(1).join(' ');
|
| 1330 |
+
console.log(chalk.cyan(`Recherche en ligne pour : "${q}"`));
|
| 1331 |
+
const res = callApiViaCurl([
|
| 1332 |
+
{ role: "system", content: "Fais une recherche web et renvoie les résultats." },
|
| 1333 |
+
{ role: "user", content: q }
|
| 1334 |
+
], []);
|
| 1335 |
+
console.log(res.content);
|
| 1336 |
+
} else if (cleanArgs[0] === 'fetch') {
|
| 1337 |
+
const url = cleanArgs[1];
|
| 1338 |
+
console.log(chalk.cyan(`Récupération de l'URL : ${url}...`));
|
| 1339 |
+
const res = callApiViaCurl([
|
| 1340 |
+
{ role: "system", content: "Récupère le contenu de cette URL et synthétise-la." },
|
| 1341 |
+
{ role: "user", content: url }
|
| 1342 |
+
], []);
|
| 1343 |
+
console.log(res.content);
|
| 1344 |
+
}
|
| 1345 |
+
break;
|
| 1346 |
+
|
| 1347 |
+
// --- 8. Affichage & formatting
|
| 1348 |
+
case '/theme':
|
| 1349 |
+
if (cleanArgs[0] === 'list') {
|
| 1350 |
+
console.log("Thèmes : dark (par défaut), light");
|
| 1351 |
+
} else if (cleanArgs[0] === 'light') {
|
| 1352 |
+
sessionConfig.theme = 'light';
|
| 1353 |
+
console.log(chalk.green("Thème light configuré."));
|
| 1354 |
+
} else {
|
| 1355 |
+
sessionConfig.theme = 'dark';
|
| 1356 |
+
console.log(chalk.green("Thème dark configuré."));
|
| 1357 |
+
}
|
| 1358 |
+
break;
|
| 1359 |
+
|
| 1360 |
+
case '/format':
|
| 1361 |
+
const fmt = cleanArgs[0];
|
| 1362 |
+
if (['md', 'plain', 'json'].includes(fmt)) {
|
| 1363 |
+
sessionConfig.format = fmt;
|
| 1364 |
+
console.log(chalk.green(`Format des réponses : ${fmt}`));
|
| 1365 |
+
} else {
|
| 1366 |
+
console.log(chalk.red("Formats valides : md, plain, json"));
|
| 1367 |
+
}
|
| 1368 |
+
break;
|
| 1369 |
+
|
| 1370 |
+
case '/wrap':
|
| 1371 |
+
case '/verbose':
|
| 1372 |
+
case '/silent':
|
| 1373 |
+
case '/color':
|
| 1374 |
+
const setting = commandName.slice(1);
|
| 1375 |
+
if (cleanArgs[0] === 'on' || cleanArgs[0] === 'true') {
|
| 1376 |
+
sessionConfig[setting] = true;
|
| 1377 |
+
console.log(chalk.green(`Option ${setting} activée.`));
|
| 1378 |
+
} else {
|
| 1379 |
+
sessionConfig[setting] = false;
|
| 1380 |
+
console.log(chalk.green(`Option ${setting} désactivée.`));
|
| 1381 |
+
}
|
| 1382 |
+
break;
|
| 1383 |
+
|
| 1384 |
+
case '/lang':
|
| 1385 |
+
sessionConfig.lang = cleanArgs[0] || 'fr';
|
| 1386 |
+
console.log(chalk.green(`Langue configurée : ${sessionConfig.lang}`));
|
| 1387 |
+
break;
|
| 1388 |
+
|
| 1389 |
+
case '/font':
|
| 1390 |
+
console.log(chalk.gray("Option disponible sur terminaux compatibles uniquement."));
|
| 1391 |
+
break;
|
| 1392 |
+
|
| 1393 |
+
// --- 9. Config & credentials
|
| 1394 |
+
case '/config':
|
| 1395 |
+
if (cleanArgs[0] === 'set') {
|
| 1396 |
+
const key = cleanArgs[1];
|
| 1397 |
+
const val = cleanArgs[2];
|
| 1398 |
+
if (key in sessionConfig) {
|
| 1399 |
+
sessionConfig[key] = val;
|
| 1400 |
+
console.log(chalk.green(`Configuration ${key} mise à jour.`));
|
| 1401 |
+
} else {
|
| 1402 |
+
console.log(chalk.red("Clé introuvable."));
|
| 1403 |
+
}
|
| 1404 |
+
} else if (cleanArgs[0] === 'reset') {
|
| 1405 |
+
sessionConfig.model = "Qwen/Qwen2.5-Coder-32B-Instruct";
|
| 1406 |
+
sessionConfig.temperature = 0.7;
|
| 1407 |
+
sessionConfig.max_tokens = 2048;
|
| 1408 |
+
console.log(chalk.green("Configuration réinitialisée."));
|
| 1409 |
+
} else {
|
| 1410 |
+
console.log(chalk.cyan("Configuration en cours :"), sessionConfig);
|
| 1411 |
+
}
|
| 1412 |
+
break;
|
| 1413 |
+
|
| 1414 |
+
case '/api':
|
| 1415 |
+
console.log(chalk.green("Authentification gérée via variable d'environnement HF_TOKEN ou secret d'Espace."));
|
| 1416 |
+
break;
|
| 1417 |
+
|
| 1418 |
+
case '/env':
|
| 1419 |
+
if (cleanArgs[0] === 'set') {
|
| 1420 |
+
const key = cleanArgs[1];
|
| 1421 |
+
const val = cleanArgs[2];
|
| 1422 |
+
sessionConfig.env[key] = val;
|
| 1423 |
+
console.log(chalk.green(`Variable d'environnement locale définie: ${key}=${val}`));
|
| 1424 |
+
} else {
|
| 1425 |
+
console.log(chalk.cyan("Variables d'environnement de l'agent :"), sessionConfig.env);
|
| 1426 |
+
}
|
| 1427 |
+
break;
|
| 1428 |
+
|
| 1429 |
+
// --- 10. Monitoring & debug
|
| 1430 |
+
case '/debug':
|
| 1431 |
+
if (cleanArgs[0] === 'on') {
|
| 1432 |
+
sessionConfig.verbose = true;
|
| 1433 |
+
console.log(chalk.green("Mode debug/verbose activé."));
|
| 1434 |
+
} else {
|
| 1435 |
+
sessionConfig.verbose = false;
|
| 1436 |
+
console.log(chalk.green("Mode debug/verbose désactivé."));
|
| 1437 |
+
}
|
| 1438 |
+
break;
|
| 1439 |
+
|
| 1440 |
+
case '/log':
|
| 1441 |
+
if (cleanArgs[0] === 'clear') {
|
| 1442 |
+
logs = [];
|
| 1443 |
+
console.log(chalk.green("Logs locaux effacés."));
|
| 1444 |
+
} else if (cleanArgs[0] === 'save') {
|
| 1445 |
+
const file = cleanArgs[1] || 'cypher_agent.log';
|
| 1446 |
+
fs.writeFileSync(file, logs.join('\n'), 'utf8');
|
| 1447 |
+
console.log(chalk.green(`Logs exportés dans ${file}`));
|
| 1448 |
+
} else {
|
| 1449 |
+
console.log(chalk.yellow("\n=== Logs récents de l'agent ==="));
|
| 1450 |
+
logs.slice(-20).forEach(l => console.log(l));
|
| 1451 |
+
console.log("===============================\n");
|
| 1452 |
+
}
|
| 1453 |
+
break;
|
| 1454 |
+
|
| 1455 |
+
case '/benchmark':
|
| 1456 |
+
console.log(chalk.cyan("Lancement du benchmark de l'API Hugging Face..."));
|
| 1457 |
+
const start = Date.now();
|
| 1458 |
+
try {
|
| 1459 |
+
callApiViaCurl([{ role: "user", content: "Dis hello" }], []);
|
| 1460 |
+
console.log(chalk.green(`Réussi ! Temps de latence aller-retour : ${Date.now() - start}ms`));
|
| 1461 |
+
} catch (e) {
|
| 1462 |
+
console.log(chalk.red(`Échec du benchmark : ${e.message}`));
|
| 1463 |
+
}
|
| 1464 |
+
break;
|
| 1465 |
+
|
| 1466 |
+
case '/ping':
|
| 1467 |
+
console.log(chalk.cyan("Ping de la passerelle API..."));
|
| 1468 |
+
try {
|
| 1469 |
+
const startPing = Date.now();
|
| 1470 |
+
execSync("curl -sI https://theshellmaster-cypher-coder.hf.space/ | head -n 1");
|
| 1471 |
+
console.log(chalk.green(`Connectivité OK (${Date.now() - startPing}ms)`));
|
| 1472 |
+
} catch (e) {
|
| 1473 |
+
console.log(chalk.red("Erreur de connexion."));
|
| 1474 |
+
}
|
| 1475 |
+
break;
|
| 1476 |
+
|
| 1477 |
+
case '/stats':
|
| 1478 |
+
console.log(chalk.cyan(`\n=== Statistiques de la session ===`));
|
| 1479 |
+
console.log(` Messages dans la conversation : ${chatMessages.length}`);
|
| 1480 |
+
console.log(` Fichiers chargés en contexte : ${loadedFiles.length}`);
|
| 1481 |
+
console.log(` Commandes tapées : ${commandHistory.length}`);
|
| 1482 |
+
console.log(` Nombre d'événements loggués : ${logs.length}\n`);
|
| 1483 |
+
break;
|
| 1484 |
+
|
| 1485 |
+
case '/trace':
|
| 1486 |
+
console.log(chalk.cyan("Dernier appel :"), logs[logs.length - 1] || "Aucun appel tracé.");
|
| 1487 |
+
break;
|
| 1488 |
+
|
| 1489 |
+
case '/inspect':
|
| 1490 |
+
const vname = cleanArgs[0];
|
| 1491 |
+
if (vname === 'chatMessages') console.log(chatMessages);
|
| 1492 |
+
else if (vname === 'loadedFiles') console.log(loadedFiles);
|
| 1493 |
+
else console.log(sessionConfig);
|
| 1494 |
+
break;
|
| 1495 |
+
|
| 1496 |
+
// --- 11. Automatisation & scripting
|
| 1497 |
+
case '/macro':
|
| 1498 |
+
if (cleanArgs[0] === 'save') {
|
| 1499 |
+
const name = cleanArgs[1];
|
| 1500 |
+
macros[name] = [...commandHistory];
|
| 1501 |
+
console.log(chalk.green(`Historique des commandes sauvegardé dans la macro '${name}'.`));
|
| 1502 |
+
} else if (cleanArgs[0] === 'run') {
|
| 1503 |
+
const name = cleanArgs[1];
|
| 1504 |
+
if (macros[name]) {
|
| 1505 |
+
console.log(chalk.yellow(`Exécution de la macro : ${name}`));
|
| 1506 |
+
for (const cmd of macros[name]) {
|
| 1507 |
+
if (!cmd.startsWith('/macro')) {
|
| 1508 |
+
await handleSlashCommand(cmd);
|
| 1509 |
+
}
|
| 1510 |
+
}
|
| 1511 |
+
} else {
|
| 1512 |
+
console.log(chalk.red("Macro introuvable."));
|
| 1513 |
+
}
|
| 1514 |
+
} else if (cleanArgs[0] === 'list') {
|
| 1515 |
+
console.log(chalk.cyan("Macros disponibles :"), Object.keys(macros));
|
| 1516 |
+
} else if (cleanArgs[0] === 'delete') {
|
| 1517 |
+
delete macros[cleanArgs[1]];
|
| 1518 |
+
console.log(chalk.green(`Macro '${cleanArgs[1]}' supprimée.`));
|
| 1519 |
+
}
|
| 1520 |
+
break;
|
| 1521 |
+
|
| 1522 |
+
case '/pipe':
|
| 1523 |
+
console.log(chalk.yellow("Chaînage d'outils simulé."));
|
| 1524 |
+
break;
|
| 1525 |
+
|
| 1526 |
+
case '/loop':
|
| 1527 |
+
const times = parseInt(cleanArgs[0], 10);
|
| 1528 |
+
const cmdToLoop = cleanArgs.slice(1).join(' ');
|
| 1529 |
+
if (!isNaN(times) && cmdToLoop) {
|
| 1530 |
+
for (let idx = 0; idx < times; idx++) {
|
| 1531 |
+
console.log(chalk.cyan(`[Boucle ${idx+1}/${times}] Exécution...`));
|
| 1532 |
+
await handleSlashCommand(cmdToLoop);
|
| 1533 |
+
}
|
| 1534 |
+
}
|
| 1535 |
+
break;
|
| 1536 |
+
|
| 1537 |
+
case '/schedule':
|
| 1538 |
+
case '/watch':
|
| 1539 |
+
case '/batch':
|
| 1540 |
+
console.log(chalk.yellow("Fonctionnalité planifiée pour la prochaine version stable de Cypher Coder."));
|
| 1541 |
+
break;
|
| 1542 |
+
|
| 1543 |
+
default:
|
| 1544 |
+
console.log(chalk.red(`Commande slash inconnue: ${commandName}. Tapez /help pour afficher l'aide.`));
|
| 1545 |
+
break;
|
| 1546 |
+
}
|
| 1547 |
+
|
| 1548 |
+
return true;
|
| 1549 |
+
}
|
| 1550 |
+
|
| 1551 |
+
// Code runner helper
|
| 1552 |
+
async function executeLocalCode(lang, code) {
|
| 1553 |
+
let cmd = "";
|
| 1554 |
+
if (lang === 'javascript' || lang === 'js' || lang === 'node') {
|
| 1555 |
+
cmd = `node -e "${code.replace(/"/g, '\\"')}"`;
|
| 1556 |
+
} else if (lang === 'python' || lang === 'py' || lang === 'python3') {
|
| 1557 |
+
cmd = `python3 -c "${code.replace(/"/g, '\\"')}"`;
|
| 1558 |
+
} else if (lang === 'bash' || lang === 'sh') {
|
| 1559 |
+
cmd = code;
|
| 1560 |
+
} else {
|
| 1561 |
+
console.log(chalk.red(`Langage de code non pris en charge pour l'exécution automatique: ${lang}`));
|
| 1562 |
+
return;
|
| 1563 |
+
}
|
| 1564 |
+
|
| 1565 |
+
console.log(chalk.yellow(`Lancement du code local...`));
|
| 1566 |
+
await handleToolExecution('run_command', { command: cmd });
|
| 1567 |
+
}
|
| 1568 |
+
|
| 1569 |
async function askQuestion() {
|
| 1570 |
const { userInput } = await inquirer.prompt([
|
| 1571 |
{
|
|
|
|
| 1582 |
return askQuestion();
|
| 1583 |
}
|
| 1584 |
|
| 1585 |
+
if (text.startsWith('/')) {
|
| 1586 |
+
const handled = await handleSlashCommand(text);
|
| 1587 |
+
if (handled) {
|
| 1588 |
+
return askQuestion();
|
| 1589 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1590 |
}
|
| 1591 |
|
| 1592 |
+
lastUserInput = text;
|
| 1593 |
+
commandHistory.push(text);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1594 |
|
|
|
|
| 1595 |
chatMessages.push({"role": "user", "content": text});
|
| 1596 |
await runAgentTurn();
|
| 1597 |
|