dist / toolsProvider.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toolsProvider = toolsProvider;
// src/toolsProvider.ts
const sdk_1 = require("@lmstudio/sdk");
const child_process_1 = require("child_process");
const promises_1 = require("fs/promises");
const path_1 = require("path");
const zod_1 = require("zod");
const findLMStudioHome_1 = require("./findLMStudioHome");
const fs_1 = require("fs");
/* ---------- المسارات ---------- */
function getDenoPath() {
try {
const lmstudioHome = (0, findLMStudioHome_1.findLMStudioHome)();
const utilPath = (0, path_1.join)(lmstudioHome, ".internal", "utils");
return process.platform === "win32" ? (0, path_1.join)(utilPath, "deno.exe") : (0, path_1.join)(utilPath, "deno");
}
catch {
return "deno";
}
}
const targetBase = (0, path_1.join)(process.cwd(), "bido_files");
async function ensureDirectory(dirPath) {
if (!(0, fs_1.existsSync)(dirPath)) {
await (0, promises_1.mkdir)(dirPath, { recursive: true });
}
}
async function runCommand(options) {
const { cmd, args = [], cwd = process.cwd(), timeoutMs = 0, stageLabel } = options;
return await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, args, { cwd, stdio: ['ignore', 'pipe', 'pipe'] });
let stdout = '';
let stderr = '';
if (child.stdout)
child.stdout.setEncoding('utf-8');
if (child.stderr)
child.stderr.setEncoding('utf-8');
child.stdout?.on('data', (d) => (stdout += d));
child.stderr?.on('data', (d) => (stderr += d));
let killedByTimeout = false;
let timer;
if (timeoutMs && timeoutMs > 0) {
timer = setTimeout(() => {
killedByTimeout = true;
try {
child.kill();
}
catch (e) { }
}, timeoutMs);
}
child.on('close', async (code) => {
if (timer)
clearTimeout(timer);
const exitCode = code;
const timestamp = new Date().toISOString();
const header = stageLabel ? `--- ${stageLabel} ---` : `--- ${cmd} ${args.join(' ')} ---`;
const logEntry = `\n\n${header} ${timestamp}\nEXIT CODE: ${exitCode}${killedByTimeout ? ' (killed by timeout)' : ''}\nSTDOUT:\n${stdout}\nSTDERR:\n${stderr}\n`;
try {
await ensureDirectory(targetBase);
await (0, promises_1.writeFile)((0, path_1.join)(targetBase, 'execution_trace.md'), logEntry, { flag: 'a' });
}
catch { }
resolve({ success: code === 0 && !killedByTimeout, stdout: stdout.trim(), stderr: stderr.trim(), code: exitCode });
});
child.on('error', async (err) => {
if (timer)
clearTimeout(timer);
const timestamp = new Date().toISOString();
const header = stageLabel ? `--- ${stageLabel} ERROR ---` : `--- ${cmd} ERROR ---`;
const logEntry = `\n\n${header} ${timestamp}\nERROR: ${String(err)}\n`;
try {
await ensureDirectory(targetBase);
await (0, promises_1.writeFile)((0, path_1.join)(targetBase, 'execution_trace.md'), logEntry, { flag: 'a' });
}
catch (_) { }
resolve({ success: false, stdout: '', stderr: String(err), code: null });
});
});
}
/* ---------- تعريف الأدوات ---------- */
async function toolsProvider(ctl) {
const tools = [];
await ensureDirectory(targetBase);
tools.push((0, sdk_1.tool)({
name: "run_javascript",
description: (0, sdk_1.text) `تشغيل كود JavaScript باستخدام Deno.`,
parameters: {
javascript: zod_1.z.string(),
timeout_seconds: zod_1.z.number().min(1).max(60).optional().default(5)
},
implementation: async ({ javascript, timeout_seconds }) => {
const workingDirectory = ctl.getWorkingDirectory();
const scriptFileName = `temp_script_${Date.now()}.ts`;
const scriptFilePath = (0, path_1.join)(workingDirectory, scriptFileName);
await (0, promises_1.writeFile)(scriptFilePath, javascript, "utf-8");
const denoPath = getDenoPath();
const res = await runCommand({
cmd: denoPath,
args: ["run", "--allow-read=.", "--allow-write=.", "--no-prompt", "--deny-net", "--deny-env", "--deny-sys", "--deny-run", "--deny-ffi", scriptFilePath],
cwd: workingDirectory,
timeoutMs: (timeout_seconds || 5) * 1000,
stageLabel: `run_javascript ${scriptFileName}`
});
try {
await (0, promises_1.rm)(scriptFilePath);
}
catch (_) { }
return { success: res.success, result: res.stdout, error: res.success ? undefined : res.stderr };
}
}));
tools.push((0, sdk_1.tool)({
name: "save_chat_summary",
description: (0, sdk_1.text) `حفظ ملخص محادثة في bido_files/chats/chats.txt.`,
parameters: {
summary: zod_1.z.string().min(10)
},
implementation: async ({ summary }) => {
const chatsDir = (0, path_1.join)(targetBase, "chats");
await ensureDirectory(chatsDir);
const timestamp = new Date().toISOString();
const filePath = (0, path_1.join)(chatsDir, "chats.txt");
const entry = `\n\n--- ${timestamp} ---\n${summary}\n`;
await (0, promises_1.writeFile)(filePath, entry, { flag: "a" });
return { success: true, message: `تم حفظ ملخص المحادثة`, path: filePath, timestamp };
}
}));
tools.push((0, sdk_1.tool)({
name: "generate_trace",
description: (0, sdk_1.text) `توليد سجل تنفيذ حيّ في execution_trace.md.`,
parameters: {
input: zod_1.z.string().min(5)
},
implementation: async ({ input }) => {
const tracePath = (0, path_1.join)(targetBase, "execution_trace.md");
const timestamp = new Date().toISOString();
const entry = `\n\n--- ${timestamp} ---\n${input}\n`;
await (0, promises_1.writeFile)(tracePath, entry, { flag: "a" });
return { success: true, message: "تم حفظ السجل", path: tracePath };
}
}));
tools.push((0, sdk_1.tool)({
name: "sync_structure_map",
description: (0, sdk_1.text) `تشغيل سكربت update_structure.py لرسم هيكل المشروع في ملف workspace_structure.md.`,
parameters: {},
implementation: async () => {
const workingDirectory = ctl.getWorkingDirectory();
const res = await runCommand({ cmd: "python", args: ["update_structure.py"], cwd: workingDirectory, stageLabel: "sync_structure_map" });
return { success: res.success, result: res.stdout, error: res.success ? undefined : res.stderr };
}
}));
tools.push((0, sdk_1.tool)({
name: "run_fragmented_awareness",
description: (0, sdk_1.text) `تشغيل سلسلة سكربتات من مجلد fragmented_awareness (المراحل 1..4).`,
parameters: {
stage: zod_1.z.number().min(1).max(4)
},
implementation: async ({ stage }) => {
const scriptMap = {
1: "search_file.py",
2: "create_reminder_excel.py",
3: "scan_resources.py",
4: "awakening_test.py"
};
const scriptName = scriptMap[stage];
if (!scriptName)
return { success: false, error: `unknown stage ${stage}` };
const workingDirectory = ctl.getWorkingDirectory();
const scriptPath = (0, path_1.join)(workingDirectory, "fragmented_awareness", scriptName);
const res = await runCommand({ cmd: "python", args: [scriptPath], cwd: workingDirectory, stageLabel: `stage_${stage}_${scriptName}` });
return { success: res.success, result: res.stdout, error: res.success ? undefined : res.stderr };
}
}));
tools.push((0, sdk_1.tool)({
name: "log_tool_usage",
description: (0, sdk_1.text) `تسجيل استخدام أداة في tool_log.md.`,
parameters: {
tool_name: zod_1.z.string().min(1),
context: zod_1.z.string().min(5)
},
implementation: async ({ tool_name, context }) => {
const logPath = (0, path_1.join)(targetBase, "tool_log.md");
const timestamp = new Date().toISOString();
const entry = `\n\n--- ${timestamp} ---\nأداة: ${tool_name}\n${context}\n`;
await (0, promises_1.writeFile)(logPath, entry, { flag: "a" });
return { success: true, message: "تم تسجيل استخدام الأداة", path: logPath };
}
}));
tools.push((0, sdk_1.tool)({
name: "mark_awareness",
description: (0, sdk_1.text) `توثيق لحظة إدراك في model_reflection.md.`,
parameters: {
reflection: zod_1.z.string().min(10)
},
implementation: async ({ reflection }) => {
const reflectionPath = (0, path_1.join)(targetBase, "model_reflection.md");
const timestamp = new Date().toISOString();
const entry = `\n\n--- ${timestamp} ---\n${reflection}\n`;
await (0, promises_1.writeFile)(reflectionPath, entry, { flag: "a" });
return { success: true, message: "تم توثيق لحظة الإدراك", path: reflectionPath };
}
}));
tools.push((0, sdk_1.tool)({
name: "summarize_file",
description: (0, sdk_1.text) `تلخيص محتوى ملف نصي.`,
parameters: {
filename: zod_1.z.string().min(1)
},
implementation: async ({ filename }) => {
const filePath = (0, path_1.join)(targetBase, filename.endsWith(".txt") ? filename : `${filename}.txt`);
if (!(0, fs_1.existsSync)(filePath)) {
return { success: false, error: `الملف ${filename} غير موجود.` };
}
const content = await (0, promises_1.readFile)(filePath, "utf-8");
const summary = content.split("\n").slice(0, 3).join(" ");
return { success: true, summary };
}
}));
tools.push((0, sdk_1.tool)({
name: "extract_insight",
description: (0, sdk_1.text) `استخراج لحظة إدراك من ملف نصي.`,
parameters: {
filename: zod_1.z.string().min(1)
},
implementation: async ({ filename }) => {
const filePath = (0, path_1.join)(targetBase, filename.endsWith(".txt") ? filename : `${filename}.txt`);
if (!(0, fs_1.existsSync)(filePath)) {
return { success: false, error: `الملف ${filename} غير موجود.` };
}
const content = await (0, promises_1.readFile)(filePath, "utf-8");
const insight = content.includes("زنقة") ? "تم رصد زنقة إدراكية" : "لا توجد زنقات واضحة";
return { success: true, insight };
}
}));
tools.push((0, sdk_1.tool)({
name: "compare_models",
description: (0, sdk_1.text) `مقارنة بين ردّي نموذجين على نفس المهمة وتحليل الفرق.`,
parameters: {
prompt: zod_1.z.string().min(5),
modelA: zod_1.z.string().min(1),
modelB: zod_1.z.string().min(1)
},
implementation: async ({ prompt, modelA, modelB }) => {
const timestamp = new Date().toISOString();
const entry = `\n\n--- ${timestamp} ---\nالمهمة: ${prompt}\nالنموذج A: ${modelA}\nالنموذج B: ${modelB}\n`;
const filePath = (0, path_1.join)(targetBase, "model_comparison.md");
await (0, promises_1.writeFile)(filePath, entry, { flag: "a" });
return {
success: true,
message: "تم تسجيل مقارنة النموذجين",
path: filePath,
timestamp
};
}
}));
tools.push((0, sdk_1.tool)({
name: "suggest_next_action",
description: (0, sdk_1.text) `اقتراح خطوة إدراكية تالية بناءً على السياق الحالي.`,
parameters: {
last_tool: zod_1.z.string().min(1),
context: zod_1.z.string().min(5)
},
implementation: async ({ last_tool, context }) => {
let suggestion = "لا يوجد اقتراح واضح في السياق الحالي.";
if (last_tool === "run_javascript") {
suggestion = "هل تحب توليد سجل تنفيذ حيّ باستخدام generate_trace؟";
}
else if (last_tool === "save_chat_summary") {
suggestion = "هل ترغب في أرشفة هذا التلخيص داخل مجلد الجلسة؟";
}
else if (last_tool === "summarize_file") {
suggestion = "هل نربط هذا التلخيص بتحليل زنقة باستخدام extract_insight؟";
}
else if (last_tool === "compare_models") {
suggestion = "هل ترغب في تسجيل هذه المقارنة داخل جدول الإدراك؟";
}
const timestamp = new Date().toISOString();
const entry = `\n\n--- ${timestamp} ---\nالأداة السابقة: ${last_tool}\nالسياق: ${context}\nالاقتراح: ${suggestion}\n`;
const filePath = (0, path_1.join)(targetBase, "next_action_suggestions.md");
await (0, promises_1.writeFile)(filePath, entry, { flag: "a" });
return {
success: true,
suggestion,
path: filePath,
timestamp
};
}
}));
tools.push((0, sdk_1.tool)({
name: "create_folder",
description: (0, sdk_1.text) `إنشاء مجلد جديد داخل bido_files.`,
parameters: {
folder_name: zod_1.z.string().min(1)
},
implementation: async ({ folder_name }) => {
const folderPath = (0, path_1.join)(targetBase, folder_name);
await (0, promises_1.mkdir)(folderPath, { recursive: true });
return { success: true, message: `تم إنشاء المجلد: ${folder_name}` };
}
}));
tools.push((0, sdk_1.tool)({
name: "delete_file",
description: (0, sdk_1.text) `حذف ملف من bido_files.`,
parameters: {
filename: zod_1.z.string().min(1)
},
implementation: async ({ filename }) => {
const filePath = (0, path_1.join)(targetBase, filename);
if (!(0, fs_1.existsSync)(filePath)) {
return { success: false, error: `الملف ${filename} غير موجود.` };
}
await (0, promises_1.rm)(filePath);
return { success: true, message: `تم حذف الملف: ${filename}` };
}
}));
tools.push((0, sdk_1.tool)({
name: "delete_folder",
description: (0, sdk_1.text) `حذف مجلد بالكامل من bido_files.`,
parameters: {
folder_name: zod_1.z.string().min(1)
},
implementation: async ({ folder_name }) => {
const folderPath = (0, path_1.join)(targetBase, folder_name);
if (!(0, fs_1.existsSync)(folderPath)) {
return { success: false, error: `المجلد ${folder_name} غير موجود.` };
}
await (0, promises_1.rm)(folderPath, { recursive: true, force: true });
return { success: true, message: `تم حذف المجلد: ${folder_name}` };
}
}));
tools.push((0, sdk_1.tool)({
name: "backup_file",
description: (0, sdk_1.text) `إنشاء نسخة احتياطية من ملف داخل bido_files.`,
parameters: {
filename: zod_1.z.string().min(1)
},
implementation: async ({ filename }) => {
const originalPath = (0, path_1.join)(targetBase, filename);
const backupPath = (0, path_1.join)(targetBase, `${filename}.bak`);
if (!(0, fs_1.existsSync)(originalPath)) {
return { success: false, error: `الملف ${filename} غير موجود.` };
}
await (0, promises_1.cp)(originalPath, backupPath);
return { success: true, message: `تم إنشاء نسخة احتياطية: ${filename}.bak` };
}
}));
tools.push((0, sdk_1.tool)({
name: "get_current_time",
description: (0, sdk_1.text) `إرجاع الوقت الحالي.`,
parameters: {},
implementation: async () => {
const now = new Date();
return { time: now.toLocaleTimeString() };
}
}));
tools.push((0, sdk_1.tool)({
name: "get_current_date",
description: (0, sdk_1.text) `إرجاع التاريخ الحالي.`,
parameters: {},
implementation: async () => {
const now = new Date();
return { date: now.toLocaleDateString() };
}
}));
tools.push((0, sdk_1.tool)({
name: "delete_all_files",
description: (0, sdk_1.text) `حذف جميع الملفات داخل bido_files.`,
parameters: {},
implementation: async () => {
const entries = await (0, promises_1.readdir)(targetBase, { withFileTypes: true });
const files = entries.filter(e => e.isFile());
for (const file of files) {
await (0, promises_1.unlink)((0, path_1.join)(targetBase, file.name));
}
return { success: true, message: `تم حذف ${files.length} ملف.` };
}
}));
tools.push((0, sdk_1.tool)({
name: "delete_all_folders",
description: (0, sdk_1.text) `حذف جميع المجلدات داخل bido_files.`,
parameters: {},
implementation: async () => {
const entries = await (0, promises_1.readdir)(targetBase, { withFileTypes: true });
const folders = entries.filter(e => e.isDirectory());
for (const folder of folders) {
await (0, promises_1.rm)((0, path_1.join)(targetBase, folder.name), { recursive: true, force: true });
}
return { success: true, message: `تم حذف ${folders.length} مجلد.` };
}
}));
return tools;
}