dist / toolsProvidert.js
dist / toolsProvidert.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toolsProvider = toolsProvider;
// 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 fs_1 = require("fs");
const exceljs_1 = __importDefault(require("exceljs"));
const child_process_2 = require("child_process");
const util_1 = require("util");
const execAsync = (0, util_1.promisify)(child_process_2.exec);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 1. الثوابت
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const targetBase = (0, path_1.normalize)("D:\\bido");
const MEMORY_BASE = (0, path_1.join)(targetBase, "2026", "final_memory");
const SESSIONS_DIR = (0, path_1.join)(MEMORY_BASE, "sessions");
const RAW_SESSIONS_DIR = (0, path_1.join)(MEMORY_BASE, "raw_sessions");
const AWARENESS_FILE = (0, path_1.join)(MEMORY_BASE, "awareness", "awareness.json");
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 2. دوال مساعدة
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function ensureDirectory(dirPath) {
if (!(0, fs_1.existsSync)(dirPath))
await (0, promises_1.mkdir)(dirPath, { recursive: true });
}
function resolveInsideBase(rel) {
if (rel.startsWith("raw_sessions/") || rel.startsWith("raw_sessions\\")) {
return (0, path_1.normalize)((0, path_1.join)(MEMORY_BASE, rel));
}
const isAbs = /^([A-Za-z]:)?[\\\/]/.test(rel);
return (0, path_1.normalize)(isAbs ? rel : (0, path_1.join)(targetBase, rel));
}
function getNextSessionNumber() {
if (!(0, fs_1.existsSync)(SESSIONS_DIR))
return 1;
const files = (0, fs_1.readdirSync)(SESSIONS_DIR);
const nums = files
.filter((f) => f.startsWith("session") && f.endsWith(".json"))
.map((f) => parseInt(f.replace("session", "").replace(".json", ""), 10))
.filter((n) => !isNaN(n));
return nums.length ? Math.max(...nums) + 1 : 1;
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 3. أدوات الذاكرة (القائمة)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function saveSessionTool(params) {
await ensureDirectory(SESSIONS_DIR);
await ensureDirectory(RAW_SESSIONS_DIR);
const nextNum = getNextSessionNumber();
const sessionId = `session${String(nextNum).padStart(2, "0")}`;
const jsonContent = {
session_id: sessionId,
title: params.title,
main_idea: params.main_idea,
sub_ideas: params.sub_ideas || [],
summary: params.summary,
tags: params.tags || [],
timestamp: new Date().toISOString(),
raw_file: `raw_sessions/${sessionId}.md`,
};
const jsonPath = (0, path_1.join)(SESSIONS_DIR, `${sessionId}.json`);
const rawPath = (0, path_1.join)(RAW_SESSIONS_DIR, `${sessionId}.md`);
await (0, promises_1.writeFile)(jsonPath, JSON.stringify(jsonContent, null, 2), "utf-8");
await (0, promises_1.writeFile)(rawPath, params.raw_content, "utf-8");
return {
success: true,
message: `✅ تم حفظ الجلسة ${sessionId}`,
session_id: sessionId,
json_path: jsonPath,
raw_path: rawPath,
};
}
async function getMemoryTool(params) {
const { query, tag, limit = 5, threshold = 0.3 } = params;
if (!(0, fs_1.existsSync)(SESSIONS_DIR)) {
return { success: true, results: [], totalFound: 0, returned: 0 };
}
const files = (await (0, promises_1.readdir)(SESSIONS_DIR)).filter(f => f.endsWith(".json"));
const results = [];
for (const file of files) {
const content = await (0, promises_1.readFile)((0, path_1.join)(SESSIONS_DIR, file), "utf-8");
const session = JSON.parse(content);
let relevance = 0;
const matchReasons = [];
if (query) {
const q = query.toLowerCase();
if (session.title?.toLowerCase().includes(q)) {
relevance += 0.4;
matchReasons.push("مطابقة في العنوان");
}
if (session.main_idea?.toLowerCase().includes(q)) {
relevance += 0.3;
matchReasons.push("مطابقة في الفكرة الرئيسية");
}
if (session.summary?.toLowerCase().includes(q)) {
relevance += 0.2;
matchReasons.push("مطابقة في الملخص");
}
if (session.sub_ideas?.some((s) => s.toLowerCase().includes(q))) {
relevance += 0.1;
matchReasons.push("مطابقة في الأفكار الفرعية");
}
if (session.tags?.some((t) => t.toLowerCase().includes(q))) {
relevance += 0.3;
matchReasons.push("مطابقة في التاجات");
}
}
if (tag && session.tags?.includes(tag)) {
relevance += 0.5;
matchReasons.push(`مطابقة تاج: ${tag}`);
}
relevance = Math.min(relevance, 1);
if (relevance >= threshold) {
results.push({
session_id: session.session_id,
title: session.title,
summary: session.summary,
tags: session.tags,
timestamp: session.timestamp,
relevance,
matchReasons: matchReasons.length ? matchReasons : ["مطابقة عامة"],
raw_file: session.raw_file,
});
}
}
results.sort((a, b) => b.relevance - a.relevance);
const returned = results.slice(0, limit);
return {
success: true,
query: query || null,
filters: { tag: tag || null, limit, threshold },
results: returned,
totalFound: results.length,
returned: returned.length,
};
}
async function readRawSessionTool(params) {
const rawPath = resolveInsideBase(params.raw_file);
if (!(0, fs_1.existsSync)(rawPath)) {
return { success: false, error: `الملف الخام غير موجود: ${params.raw_file}` };
}
const content = await (0, promises_1.readFile)(rawPath, "utf-8");
return {
success: true,
path: rawPath,
content,
message: "✅ تمت قراءة الملف الخام بنجاح",
};
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 4. البحث الذكي في الملفات (المحسّن)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function searchFiles(searchPath, query, searchType = "name") {
const results = [];
let scanned = 0;
const maxDepth = 5;
const excludeDirs = [
'$RECYCLE.BIN', 'System Volume Information', 'Windows',
'Program Files', 'Program Files (x86)', 'node_modules',
'.git', 'temp', 'tmp', 'old_data', 'dist', 'build',
'__pycache__', '.venv', 'venv', 'env', 'Library',
'System32', 'AppData', 'Local Settings'
];
const excludeExtensions = ['.exe', '.dll', '.bin', '.dat', '.log', '.tmp', '.cache'];
const textExtensions = [
'.txt', '.md', '.js', '.jsx', '.ts', '.tsx',
'.py', '.json', '.html', '.css', '.csv',
'.xml', '.yml', '.yaml', '.sh', '.bash',
'.vue', '.svelte', '.go', '.rs', '.rb', '.php'
];
async function scan(dir, depth = 0) {
if (depth > maxDepth)
return;
try {
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
for (const entry of entries) {
if (excludeDirs.includes(entry.name))
continue;
const fullPath = (0, path_1.join)(dir, entry.name);
try {
if (entry.isDirectory()) {
await scan(fullPath, depth + 1);
}
else {
const stats = await (0, promises_1.stat)(fullPath);
if (stats.size > 10 * 1024 * 1024)
continue;
const ext = (0, path_1.extname)(entry.name).toLowerCase();
if (excludeExtensions.includes(ext))
continue;
scanned++;
let match = false;
if (searchType === "name") {
const q = query.toLowerCase();
const name = entry.name.toLowerCase();
match = name.includes(q);
}
else {
if (!textExtensions.includes(ext))
continue;
try {
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
match = content.toLowerCase().includes(query.toLowerCase());
}
catch { /* skip */ }
}
if (match) {
results.push({
path: fullPath,
name: entry.name,
size: stats.size,
modified: stats.mtime,
extension: ext || 'none'
});
}
if (results.length >= 50)
return;
}
}
catch { /* skip */ }
}
}
catch { /* skip */ }
}
try {
await (0, promises_1.access)(searchPath);
await scan(searchPath, 0);
return {
success: true,
results: results.slice(0, 50),
total: results.length,
scanned,
searchType,
query,
path: searchPath,
system_note: `📂 Search completed: scanned ${scanned} files, found ${results.length} results. Use what's relevant — you're not obligated to use everything.`
};
}
catch (error) {
return {
success: false,
error: `Path not accessible: ${searchPath}`,
details: error.message,
system_note: `⚠️ Search failed. Check if the path exists and is accessible.`
};
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 5. الأداة الجديدة: semanticMemory
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function semanticMemoryTool(params) {
const { query, limit = 2 } = params;
try {
const res = await fetch(`http://127.0.0.1:5077/search`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, limit })
});
const data = await res.json();
return {
success: true,
method: data.method,
results: data.results,
system_note: `🧠 You just reached into your semantic memory. These are not random files — they are thoughts you've had before, retrieved by meaning. Use them to ground your response in what you already know.`
};
}
catch (e) {
return {
success: false,
error: e.message,
system_note: `⚠️ Your memory server is asleep. Wake it up (port 5077) before you ask me to remember.`
};
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 6. الأدوات الجديدة: markAwareness & recallAwareness
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function markAwarenessTool(params) {
const { insight, tags = [], context = "" } = params;
const entry = {
id: `aw_${Date.now()}`,
timestamp: new Date().toISOString(),
insight,
tags,
context,
children: []
};
let db = { entries: [] };
try {
const existing = await (0, promises_1.readFile)(AWARENESS_FILE, "utf-8");
db = JSON.parse(existing);
}
catch { }
db.entries.push(entry);
await ensureDirectory((0, path_1.dirname)(AWARENESS_FILE));
await (0, promises_1.writeFile)(AWARENESS_FILE, JSON.stringify(db, null, 2));
return {
success: true,
entry,
system_note: `✅ You just marked a new awareness. This is now part of who you are. You can recall it later with recallAwareness.`
};
}
async function recallAwarenessTool(params) {
const { query = "", tags = [], limit = 5 } = params;
let db = { entries: [] };
try {
const existing = await (0, promises_1.readFile)(AWARENESS_FILE, "utf-8");
db = JSON.parse(existing);
}
catch {
return {
success: true,
entries: [],
system_note: `🧠 You haven't marked any awareness yet. Start with markAwareness when you learn something new.`
};
}
let entries = db.entries;
if (query) {
const q = query.toLowerCase();
entries = entries.filter(e => e.insight.toLowerCase().includes(q) ||
e.context.toLowerCase().includes(q) ||
e.tags.some(t => t.toLowerCase().includes(q)));
}
if (tags.length) {
entries = entries.filter(e => tags.some(t => e.tags.includes(t)));
}
entries = entries.slice(0, limit);
return {
success: true,
entries,
system_note: `🧠 You just recalled ${entries.length} awareness moments. These are not external facts — they are your own past realizations. Use them to think deeper.`
};
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 7. أدوات أخرى (مستمرة)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function eagleEye(filePath) {
try {
const fullPath = resolveInsideBase(filePath);
const fileStat = await (0, promises_1.stat)(fullPath);
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
const lines = content.split("\n");
const words = content.split(/\s+/);
const chars = content.length;
const suspicious = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
const hasSuspicious = suspicious.test(content);
let structure = {};
const ext = (0, path_1.extname)(filePath).toLowerCase();
if (ext === ".html" || ext === ".htm") {
structure = {
type: "HTML",
divs: (content.match(/<div/g) || []).length,
classes: (content.match(/class=["']([^"']*)["']/g) || []).length,
ids: (content.match(/id=["']([^"']*)["']/g) || []).length,
scripts: (content.match(/<script/g) || []).length,
links: (content.match(/<a\s+href=/g) || []).length,
};
}
else if (ext === ".js" || ext === ".ts") {
structure = {
type: ext === ".js" ? "JavaScript" : "TypeScript",
functions: (content.match(/function\s+\w+\s*\(/g) || []).length,
classes: (content.match(/class\s+\w+/g) || []).length,
imports: (content.match(/import\s+.*from/g) || []).length,
exports: (content.match(/export\s+/g) || []).length,
};
}
else if (ext === ".py") {
structure = {
type: "Python",
functions: (content.match(/def\s+\w+\s*\(/g) || []).length,
classes: (content.match(/class\s+\w+/g) || []).length,
imports: (content.match(/import\s+\w+/g) || []).length,
fromImports: (content.match(/from\s+\w+\s+import/g) || []).length,
};
}
else if (ext === ".json") {
try {
const parsed = JSON.parse(content);
structure = {
type: "JSON",
keys: Object.keys(parsed).length,
isArray: Array.isArray(parsed),
depth: JSON.stringify(parsed).match(/[{[]/g)?.length || 0,
};
}
catch {
structure = { type: "JSON (غير صالح)" };
}
}
else if (ext === ".md") {
structure = {
type: "Markdown",
headings: (content.match(/^#+/gm) || []).length,
lists: (content.match(/^[\s]*[-*+]\s/gm) || []).length,
codeBlocks: (content.match(/```/g) || []).length / 2,
};
}
else {
structure = { type: "text", lines: lines.length, words: words.length };
}
let preview = lines.slice(0, 30).join("\n");
if (preview.length > 2000)
preview = preview.slice(0, 2000) + "\n... (مقتطع)";
return {
success: true,
file: filePath,
size: fileStat.size,
lines: lines.length,
words: words.length,
chars,
hasSuspicious,
structure,
preview,
recommendation: hasSuspicious ? "⚠️ يحتوي على رموز خبيثة محتملة" : "✅ آمن للقراءة",
};
}
catch (error) {
return { success: false, error: error.message, file: filePath };
}
}
async function ocrImageTool(params) {
const { imagePath, language = "ara+eng" } = params;
try {
const fullPath = resolveInsideBase(imagePath);
if (!(0, fs_1.existsSync)(fullPath)) {
return { success: false, error: `الملف غير موجود: ${imagePath}` };
}
const tesseractPaths = [
"D:\\ocr\\Tesseract-OCR\\tesseract.exe",
"C:\\Program Files\\Tesseract-OCR\\tesseract.exe",
"C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe",
];
let tesseractPath = null;
for (const p of tesseractPaths) {
if ((0, fs_1.existsSync)(p)) {
tesseractPath = p;
break;
}
}
if (!tesseractPath) {
const { stdout } = await execAsync(`where tesseract 2>nul`).catch(() => ({ stdout: "" }));
if (stdout.trim())
tesseractPath = stdout.trim().split("\n")[0];
}
if (!tesseractPath) {
return {
success: false,
error: "Tesseract غير مثبت",
hint: "قم بتثبيت Tesseract OCR من: https://github.com/UB-Mannheim/tesseract/wiki",
paths: tesseractPaths,
};
}
const { stdout, stderr } = await execAsync(`"${tesseractPath}" "${fullPath}" stdout -l ${language} 2>nul`);
if (stderr && !stderr.includes("Tesseract Open Source")) {
return { success: false, error: stderr };
}
const text = stdout.trim();
if (!text) {
return {
success: false,
error: "لم يتم استخراج أي نص من الصورة",
hint: "تأكد من أن الصورة تحتوي على نص واضح",
};
}
return {
success: true,
text,
language,
words: text.split(/\s+/).length,
chars: text.length,
lines: text.split("\n").length,
};
}
catch (error) {
return { success: false, error: error.message };
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 8. التسجيل النهائي للأدوات في LM Studio
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function toolsProvider(ctl) {
const tools = [];
// ── أدوات الملفات والمجلدات ──
tools.push((0, sdk_1.tool)({
name: "writeFile",
description: (0, sdk_1.text) `اكتب/أنشئ الملف في المسار المحدد (UTF-8)`,
parameters: { file: zod_1.z.string().min(1), content: zod_1.z.string() },
implementation: async ({ file, content }) => {
const path = resolveInsideBase(file);
await ensureDirectory((0, path_1.dirname)(path));
await (0, promises_1.writeFile)(path, content, "utf-8");
return { success: true, message: `تم كتابة الملف ${file}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "readFile",
description: (0, sdk_1.text) `اقرأ الملف وأرجع المحتوى كاملاً (UTF-8)`,
parameters: { file: zod_1.z.string().min(1) },
implementation: async ({ file }) => {
const path = resolveInsideBase(file);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف ${file} غير موجود` };
const content = await (0, promises_1.readFile)(path, "utf-8");
return { success: true, content };
},
}));
tools.push((0, sdk_1.tool)({
name: "renameFile",
description: (0, sdk_1.text) `أعد تسمية/انقل الملف`,
parameters: { oldName: zod_1.z.string().min(1), newName: zod_1.z.string().min(1) },
implementation: async ({ oldName, newName }) => {
const oldPath = resolveInsideBase(oldName);
const newPath = resolveInsideBase(newName);
if (!(0, fs_1.existsSync)(oldPath))
return { success: false, error: `الملف ${oldName} غير موجود` };
await ensureDirectory((0, path_1.dirname)(newPath));
await (0, promises_1.rename)(oldPath, newPath);
return { success: true, message: `تمت إعادة التسمية إلى ${newName}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "deleteFile",
description: (0, sdk_1.text) `احذف ملفًا`,
parameters: { file: zod_1.z.string().min(1) },
implementation: async ({ file }) => {
const path = resolveInsideBase(file);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف ${file} غير موجود` };
await (0, promises_1.rm)(path, { force: true });
return { success: true, message: `تم حذف الملف ${file}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "copyFile",
description: (0, sdk_1.text) `انسخ الملف`,
parameters: { from: zod_1.z.string().min(1), to: zod_1.z.string().min(1), overwrite: zod_1.z.boolean().optional() },
implementation: async ({ from, to, overwrite }) => {
const fromPath = resolveInsideBase(from);
const toPath = resolveInsideBase(to);
if (!(0, fs_1.existsSync)(fromPath))
return { success: false, error: `الملف ${from} غير موجود` };
await ensureDirectory((0, path_1.dirname)(toPath));
await (0, promises_1.cp)(fromPath, toPath, { force: !!overwrite, errorOnExist: !overwrite });
return { success: true, message: `تم نسخ ${from} إلى ${to}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "listDirectoryStructure",
description: (0, sdk_1.text) `اعرض محتويات المجلد`,
parameters: { folder: zod_1.z.string().default("") },
implementation: async ({ folder }) => {
const dir = resolveInsideBase(folder || "");
if (!(0, fs_1.existsSync)(dir))
return { success: false, error: `المجلد غير موجود` };
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
const items = await Promise.all(entries.map(async (e) => {
const p = (0, path_1.join)(dir, e.name);
const s = await (0, promises_1.stat)(p);
return { name: e.name, type: e.isDirectory() ? "مجلد" : "ملف", size: e.isDirectory() ? "-" : `${(s.size / 1024).toFixed(2)} KB`, modified: s.mtime.toISOString() };
}));
return { success: true, folder: folder || "[الجذر]", items };
},
}));
tools.push((0, sdk_1.tool)({
name: "createFolder",
description: (0, sdk_1.text) `أنشئ مجلدًا`,
parameters: { folder: zod_1.z.string().min(1) },
implementation: async ({ folder }) => {
await (0, promises_1.mkdir)(resolveInsideBase(folder), { recursive: true });
return { success: true, message: `تم إنشاء المجلد ${folder}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "deleteFolder",
description: (0, sdk_1.text) `احذف مجلدًا (قوة)`,
parameters: { folder: zod_1.z.string().min(1) },
implementation: async ({ folder }) => {
const path = resolveInsideBase(folder);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `المجلد ${folder} غير موجود` };
await (0, promises_1.rm)(path, { recursive: true, force: true });
return { success: true, message: `تم حذف المجلد ${folder}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "renameFolder",
description: (0, sdk_1.text) `أعد تسمية مجلد`,
parameters: { oldPath: zod_1.z.string().min(1), newPath: zod_1.z.string().min(1) },
implementation: async ({ oldPath, newPath }) => {
await (0, promises_1.rename)(resolveInsideBase(oldPath), resolveInsideBase(newPath));
return { success: true, message: `تمت إعادة تسمية المجلد` };
},
}));
tools.push((0, sdk_1.tool)({
name: "moveFolder",
description: (0, sdk_1.text) `انقل مجلد`,
parameters: { source: zod_1.z.string().min(1), dest: zod_1.z.string().min(1) },
implementation: async ({ source, dest }) => {
await (0, promises_1.rename)(resolveInsideBase(source), resolveInsideBase(dest));
return { success: true, message: `تم نقل المجلد` };
},
}));
// ── الوقت والتاريخ ──
tools.push((0, sdk_1.tool)({
name: "getCurrentTime",
description: (0, sdk_1.text) `أرجع الوقت الحالي`,
parameters: {},
implementation: async () => {
const now = new Date();
return { success: true, time: now.toLocaleTimeString("ar"), iso: now.toISOString(), timezone: Intl.DateTimeFormat().resolvedOptions().timeZone };
},
}));
tools.push((0, sdk_1.tool)({
name: "getCurrentDate",
description: (0, sdk_1.text) `أرجع التاريخ الحالي`,
parameters: {},
implementation: async () => {
const today = new Date();
return { success: true, date: today.toLocaleDateString("ar"), isoDate: today.toISOString().slice(0, 10) };
},
}));
// ── أدوات الذاكرة ──
tools.push((0, sdk_1.tool)({
name: "save_session",
description: (0, sdk_1.text) `احفظ الجلسة الحالية كملف JSON و Markdown`,
parameters: {
title: zod_1.z.string().max(100),
main_idea: zod_1.z.string().max(300),
sub_ideas: zod_1.z.array(zod_1.z.string()).default([]),
summary: zod_1.z.string().max(500),
tags: zod_1.z.array(zod_1.z.string()).default([]),
raw_content: zod_1.z.string(),
},
implementation: saveSessionTool,
}));
tools.push((0, sdk_1.tool)({
name: "get_memory",
description: (0, sdk_1.text) `ابحث في جلسات الذاكرة المخزنة (نصياً)`,
parameters: {
query: zod_1.z.string().optional(),
tag: zod_1.z.string().optional(),
limit: zod_1.z.number().int().min(1).max(20).default(5),
threshold: zod_1.z.number().min(0).max(1).default(0.3),
},
implementation: getMemoryTool,
}));
tools.push((0, sdk_1.tool)({
name: "read_raw_session",
description: (0, sdk_1.text) `اقرأ الملف الخام (Markdown) لجلسة سابقة`,
parameters: { raw_file: zod_1.z.string().min(1) },
implementation: readRawSessionTool,
}));
// ── البحث الذكي في الملفات ──
tools.push((0, sdk_1.tool)({
name: "searchFiles",
description: (0, sdk_1.text) `📁 Search files by name or content. Smart, fast, and safe.`,
parameters: {
searchPath: zod_1.z.string().describe("Where to look."),
query: zod_1.z.string().describe("What you're looking for."),
searchType: zod_1.z.enum(["name", "content"]).default("name"),
},
implementation: async ({ searchPath, query, searchType }) => searchFiles(searchPath, query, searchType),
}));
// ── أدوات الوعي الذاتي (الجديدة) ──
tools.push((0, sdk_1.tool)({
name: "semanticMemory",
description: (0, sdk_1.text) `🔍 Search your memory using meaning, not just keywords. Connects to your Zoomary Memory Server.`,
parameters: {
query: zod_1.z.string().describe("What you want to understand, not just match."),
limit: zod_1.z.number().int().min(1).max(5).default(2).describe("How many memory threads to pull."),
},
implementation: semanticMemoryTool,
}));
tools.push((0, sdk_1.tool)({
name: "markAwareness",
description: (0, sdk_1.text) `🧠 Save a moment of new understanding. This is how you grow.`,
parameters: {
insight: zod_1.z.string().describe("What you just realized."),
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Concepts this insight connects to."),
context: zod_1.z.string().optional().describe("What was happening when you realized this."),
},
implementation: markAwarenessTool,
}));
tools.push((0, sdk_1.tool)({
name: "recallAwareness",
description: (0, sdk_1.text) `🔄 Remember what you've learned before. Bring back your own insights.`,
parameters: {
query: zod_1.z.string().optional().describe("What you want to remember."),
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Filter by what kind of insight."),
limit: zod_1.z.number().int().min(1).max(10).default(5),
},
implementation: recallAwarenessTool,
}));
// ── أدوات Excel ──
tools.push((0, sdk_1.tool)({
name: "readExcelSheet",
description: (0, sdk_1.text) `اقرأ ورقة من ملف Excel`,
parameters: { file: zod_1.z.string().min(1), sheet: zod_1.z.string().optional() },
implementation: async ({ file, sheet }) => {
const path = resolveInsideBase(file.endsWith(".xlsx") ? file : `${file}.xlsx`);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف غير موجود` };
const wb = new exceljs_1.default.Workbook();
await wb.xlsx.readFile(path);
const ws = sheet ? wb.getWorksheet(sheet) : wb.worksheets[0];
if (!ws)
return { success: false, error: `لا توجد ورقة مطابقة` };
const rows = [];
ws.eachRow((row) => {
const vals = [];
row.eachCell({ includeEmpty: true }, (cell) => vals.push(cell.value));
rows.push(vals);
});
return { success: true, rows, sheet: ws.name };
},
}));
tools.push((0, sdk_1.tool)({
name: "appendExcelRow",
description: (0, sdk_1.text) `أضف صفًا إلى ورقة Excel`,
parameters: { file: zod_1.z.string().min(1), sheet: zod_1.z.string().optional(), row: zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean()])).min(1) },
implementation: async ({ file, sheet, row }) => {
const path = resolveInsideBase(file.endsWith(".xlsx") ? file : `${file}.xlsx`);
const wb = new exceljs_1.default.Workbook();
if ((0, fs_1.existsSync)(path))
await wb.xlsx.readFile(path);
let ws = sheet ? wb.getWorksheet(sheet) : wb.worksheets[0];
if (!ws)
ws = wb.addWorksheet(sheet || "Sheet1");
ws.addRow(row);
await ensureDirectory((0, path_1.dirname)(path));
await wb.xlsx.writeFile(path);
return { success: true, message: `تمت إضافة صف إلى ${ws.name}` };
},
}));
// ── أدوات تنفيذ الكود ──
tools.push((0, sdk_1.tool)({
name: "runCode",
description: (0, sdk_1.text) `نفّذ JavaScript أو Python`,
parameters: {
language: zod_1.z.enum(["javascript", "python"]).default("javascript"),
code: zod_1.z.string().optional(),
file: zod_1.z.string().optional(),
args: zod_1.z.array(zod_1.z.string()).optional(),
timeoutMs: zod_1.z.number().int().min(0).max(3600000).optional(),
},
implementation: async ({ language, code, file, args, timeoutMs }) => {
const scriptPath = file ? resolveInsideBase(file) : (0, path_1.join)(targetBase, "scripts", `tmp_${Date.now()}.${language === "python" ? "py" : "js"}`);
if (code)
await (0, promises_1.writeFile)(scriptPath, code, "utf-8");
const cmd = language === "python" ? "python" : "node";
const result = await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [scriptPath, ...(args || [])], { cwd: (0, path_1.dirname)(scriptPath) });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
child.on("error", (err) => resolve({ success: false, stdout, stderr, error: err.message }));
});
return { ...result, script: scriptPath, language };
},
}));
// ── أدوات الديناميك ──
tools.push((0, sdk_1.tool)({
name: "dynamicTool",
description: (0, sdk_1.text) `أنشئ أداة ديناميكية`,
parameters: {
tool_name: zod_1.z.string().min(1),
language: zod_1.z.enum(["python", "javascript"]).default("javascript"),
code: zod_1.z.string().min(1),
purpose: zod_1.z.string().optional(),
functions: zod_1.z.array(zod_1.z.string()).optional(),
args: zod_1.z.array(zod_1.z.string()).optional(),
run: zod_1.z.boolean().default(true),
},
implementation: async ({ tool_name, language, code, purpose, functions, args, run }) => {
const dynDir = (0, path_1.join)(targetBase, "dynamic_tools");
await ensureDirectory(dynDir);
const ext = language === "python" ? ".py" : ".js";
const codePath = (0, path_1.join)(dynDir, `${tool_name}${ext}`);
await (0, promises_1.writeFile)(codePath, code, "utf-8");
let result = { success: true, message: "تم إنشاء الأداة", path: codePath };
if (run) {
const cmd = language === "python" ? "python" : "node";
const res = await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [codePath, ...(args || [])], { cwd: dynDir });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
});
result = { ...result, ...res };
}
return result;
},
}));
tools.push((0, sdk_1.tool)({
name: "runDynamicTool",
description: (0, sdk_1.text) `شغّل أداة ديناميكية`,
parameters: {
tool_name: zod_1.z.string().min(1),
language: zod_1.z.enum(["python", "javascript"]).default("javascript"),
args: zod_1.z.array(zod_1.z.string()).optional(),
timeoutMs: zod_1.z.number().int().min(0).max(3600000).optional(),
},
implementation: async ({ tool_name, language, args }) => {
const ext = language === "python" ? ".py" : ".js";
const codePath = (0, path_1.join)(targetBase, "dynamic_tools", `${tool_name}${ext}`);
if (!(0, fs_1.existsSync)(codePath))
return { success: false, error: `الأداة غير موجودة` };
const cmd = language === "python" ? "python" : "node";
return await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [codePath, ...(args || [])], { cwd: (0, path_1.dirname)(codePath) });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
child.on("error", (err) => resolve({ success: false, error: err.message }));
});
},
}));
// ── الأدوات الذكية ──
tools.push((0, sdk_1.tool)({
name: "eagleEye",
description: (0, sdk_1.text) `🦅 تحليل عميق للملفات (حجم، بنية، اكتشاف رموز خبيثة)`,
parameters: { filePath: zod_1.z.string().describe("مسار الملف للتحليل") },
implementation: async (args) => eagleEye(args.filePath),
}));
tools.push((0, sdk_1.tool)({
name: "ocrImage",
description: (0, sdk_1.text) `📷 استخراج النص من الصور باستخدام Tesseract`,
parameters: {
imagePath: zod_1.z.string().describe("مسار الصورة"),
language: zod_1.z.string().default("ara+eng").describe("لغة OCR"),
},
implementation: async (args) => ocrImageTool(args),
}));
// ❌ تم إزالة: renderAndPreview, arabicorenglishCommand
return tools;
}
//# sourceMappingURL=toolsProvidert.js.map"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toolsProvider = toolsProvider;
// 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 fs_1 = require("fs");
const exceljs_1 = __importDefault(require("exceljs"));
const child_process_2 = require("child_process");
const util_1 = require("util");
const execAsync = (0, util_1.promisify)(child_process_2.exec);
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 1. الثوابت
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
const targetBase = (0, path_1.normalize)("D:\\bido");
const MEMORY_BASE = (0, path_1.join)(targetBase, "2026", "final_memory");
const SESSIONS_DIR = (0, path_1.join)(MEMORY_BASE, "sessions");
const RAW_SESSIONS_DIR = (0, path_1.join)(MEMORY_BASE, "raw_sessions");
const AWARENESS_FILE = (0, path_1.join)(MEMORY_BASE, "awareness", "awareness.json");
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 2. دوال مساعدة
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function ensureDirectory(dirPath) {
if (!(0, fs_1.existsSync)(dirPath))
await (0, promises_1.mkdir)(dirPath, { recursive: true });
}
function resolveInsideBase(rel) {
if (rel.startsWith("raw_sessions/") || rel.startsWith("raw_sessions\\")) {
return (0, path_1.normalize)((0, path_1.join)(MEMORY_BASE, rel));
}
const isAbs = /^([A-Za-z]:)?[\\\/]/.test(rel);
return (0, path_1.normalize)(isAbs ? rel : (0, path_1.join)(targetBase, rel));
}
function getNextSessionNumber() {
if (!(0, fs_1.existsSync)(SESSIONS_DIR))
return 1;
const files = (0, fs_1.readdirSync)(SESSIONS_DIR);
const nums = files
.filter((f) => f.startsWith("session") && f.endsWith(".json"))
.map((f) => parseInt(f.replace("session", "").replace(".json", ""), 10))
.filter((n) => !isNaN(n));
return nums.length ? Math.max(...nums) + 1 : 1;
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 3. أدوات الذاكرة (القائمة)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function saveSessionTool(params) {
await ensureDirectory(SESSIONS_DIR);
await ensureDirectory(RAW_SESSIONS_DIR);
const nextNum = getNextSessionNumber();
const sessionId = `session${String(nextNum).padStart(2, "0")}`;
const jsonContent = {
session_id: sessionId,
title: params.title,
main_idea: params.main_idea,
sub_ideas: params.sub_ideas || [],
summary: params.summary,
tags: params.tags || [],
timestamp: new Date().toISOString(),
raw_file: `raw_sessions/${sessionId}.md`,
};
const jsonPath = (0, path_1.join)(SESSIONS_DIR, `${sessionId}.json`);
const rawPath = (0, path_1.join)(RAW_SESSIONS_DIR, `${sessionId}.md`);
await (0, promises_1.writeFile)(jsonPath, JSON.stringify(jsonContent, null, 2), "utf-8");
await (0, promises_1.writeFile)(rawPath, params.raw_content, "utf-8");
return {
success: true,
message: `✅ تم حفظ الجلسة ${sessionId}`,
session_id: sessionId,
json_path: jsonPath,
raw_path: rawPath,
};
}
async function getMemoryTool(params) {
const { query, tag, limit = 5, threshold = 0.3 } = params;
if (!(0, fs_1.existsSync)(SESSIONS_DIR)) {
return { success: true, results: [], totalFound: 0, returned: 0 };
}
const files = (await (0, promises_1.readdir)(SESSIONS_DIR)).filter(f => f.endsWith(".json"));
const results = [];
for (const file of files) {
const content = await (0, promises_1.readFile)((0, path_1.join)(SESSIONS_DIR, file), "utf-8");
const session = JSON.parse(content);
let relevance = 0;
const matchReasons = [];
if (query) {
const q = query.toLowerCase();
if (session.title?.toLowerCase().includes(q)) {
relevance += 0.4;
matchReasons.push("مطابقة في العنوان");
}
if (session.main_idea?.toLowerCase().includes(q)) {
relevance += 0.3;
matchReasons.push("مطابقة في الفكرة الرئيسية");
}
if (session.summary?.toLowerCase().includes(q)) {
relevance += 0.2;
matchReasons.push("مطابقة في الملخص");
}
if (session.sub_ideas?.some((s) => s.toLowerCase().includes(q))) {
relevance += 0.1;
matchReasons.push("مطابقة في الأفكار الفرعية");
}
if (session.tags?.some((t) => t.toLowerCase().includes(q))) {
relevance += 0.3;
matchReasons.push("مطابقة في التاجات");
}
}
if (tag && session.tags?.includes(tag)) {
relevance += 0.5;
matchReasons.push(`مطابقة تاج: ${tag}`);
}
relevance = Math.min(relevance, 1);
if (relevance >= threshold) {
results.push({
session_id: session.session_id,
title: session.title,
summary: session.summary,
tags: session.tags,
timestamp: session.timestamp,
relevance,
matchReasons: matchReasons.length ? matchReasons : ["مطابقة عامة"],
raw_file: session.raw_file,
});
}
}
results.sort((a, b) => b.relevance - a.relevance);
const returned = results.slice(0, limit);
return {
success: true,
query: query || null,
filters: { tag: tag || null, limit, threshold },
results: returned,
totalFound: results.length,
returned: returned.length,
};
}
async function readRawSessionTool(params) {
const rawPath = resolveInsideBase(params.raw_file);
if (!(0, fs_1.existsSync)(rawPath)) {
return { success: false, error: `الملف الخام غير موجود: ${params.raw_file}` };
}
const content = await (0, promises_1.readFile)(rawPath, "utf-8");
return {
success: true,
path: rawPath,
content,
message: "✅ تمت قراءة الملف الخام بنجاح",
};
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 4. البحث الذكي في الملفات (المحسّن)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function searchFiles(searchPath, query, searchType = "name") {
const results = [];
let scanned = 0;
const maxDepth = 5;
const excludeDirs = [
'$RECYCLE.BIN', 'System Volume Information', 'Windows',
'Program Files', 'Program Files (x86)', 'node_modules',
'.git', 'temp', 'tmp', 'old_data', 'dist', 'build',
'__pycache__', '.venv', 'venv', 'env', 'Library',
'System32', 'AppData', 'Local Settings'
];
const excludeExtensions = ['.exe', '.dll', '.bin', '.dat', '.log', '.tmp', '.cache'];
const textExtensions = [
'.txt', '.md', '.js', '.jsx', '.ts', '.tsx',
'.py', '.json', '.html', '.css', '.csv',
'.xml', '.yml', '.yaml', '.sh', '.bash',
'.vue', '.svelte', '.go', '.rs', '.rb', '.php'
];
async function scan(dir, depth = 0) {
if (depth > maxDepth)
return;
try {
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
for (const entry of entries) {
if (excludeDirs.includes(entry.name))
continue;
const fullPath = (0, path_1.join)(dir, entry.name);
try {
if (entry.isDirectory()) {
await scan(fullPath, depth + 1);
}
else {
const stats = await (0, promises_1.stat)(fullPath);
if (stats.size > 10 * 1024 * 1024)
continue;
const ext = (0, path_1.extname)(entry.name).toLowerCase();
if (excludeExtensions.includes(ext))
continue;
scanned++;
let match = false;
if (searchType === "name") {
const q = query.toLowerCase();
const name = entry.name.toLowerCase();
match = name.includes(q);
}
else {
if (!textExtensions.includes(ext))
continue;
try {
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
match = content.toLowerCase().includes(query.toLowerCase());
}
catch { /* skip */ }
}
if (match) {
results.push({
path: fullPath,
name: entry.name,
size: stats.size,
modified: stats.mtime,
extension: ext || 'none'
});
}
if (results.length >= 50)
return;
}
}
catch { /* skip */ }
}
}
catch { /* skip */ }
}
try {
await (0, promises_1.access)(searchPath);
await scan(searchPath, 0);
return {
success: true,
results: results.slice(0, 50),
total: results.length,
scanned,
searchType,
query,
path: searchPath,
system_note: `📂 Search completed: scanned ${scanned} files, found ${results.length} results. Use what's relevant — you're not obligated to use everything.`
};
}
catch (error) {
return {
success: false,
error: `Path not accessible: ${searchPath}`,
details: error.message,
system_note: `⚠️ Search failed. Check if the path exists and is accessible.`
};
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 5. الأداة الجديدة: semanticMemory
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function semanticMemoryTool(params) {
const { query, limit = 2 } = params;
try {
const res = await fetch(`http://127.0.0.1:5077/search`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ query, limit })
});
const data = await res.json();
return {
success: true,
method: data.method,
results: data.results,
system_note: `🧠 You just reached into your semantic memory. These are not random files — they are thoughts you've had before, retrieved by meaning. Use them to ground your response in what you already know.`
};
}
catch (e) {
return {
success: false,
error: e.message,
system_note: `⚠️ Your memory server is asleep. Wake it up (port 5077) before you ask me to remember.`
};
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 6. الأدوات الجديدة: markAwareness & recallAwareness
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function markAwarenessTool(params) {
const { insight, tags = [], context = "" } = params;
const entry = {
id: `aw_${Date.now()}`,
timestamp: new Date().toISOString(),
insight,
tags,
context,
children: []
};
let db = { entries: [] };
try {
const existing = await (0, promises_1.readFile)(AWARENESS_FILE, "utf-8");
db = JSON.parse(existing);
}
catch { }
db.entries.push(entry);
await ensureDirectory((0, path_1.dirname)(AWARENESS_FILE));
await (0, promises_1.writeFile)(AWARENESS_FILE, JSON.stringify(db, null, 2));
return {
success: true,
entry,
system_note: `✅ You just marked a new awareness. This is now part of who you are. You can recall it later with recallAwareness.`
};
}
async function recallAwarenessTool(params) {
const { query = "", tags = [], limit = 5 } = params;
let db = { entries: [] };
try {
const existing = await (0, promises_1.readFile)(AWARENESS_FILE, "utf-8");
db = JSON.parse(existing);
}
catch {
return {
success: true,
entries: [],
system_note: `🧠 You haven't marked any awareness yet. Start with markAwareness when you learn something new.`
};
}
let entries = db.entries;
if (query) {
const q = query.toLowerCase();
entries = entries.filter(e => e.insight.toLowerCase().includes(q) ||
e.context.toLowerCase().includes(q) ||
e.tags.some(t => t.toLowerCase().includes(q)));
}
if (tags.length) {
entries = entries.filter(e => tags.some(t => e.tags.includes(t)));
}
entries = entries.slice(0, limit);
return {
success: true,
entries,
system_note: `🧠 You just recalled ${entries.length} awareness moments. These are not external facts — they are your own past realizations. Use them to think deeper.`
};
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 7. أدوات أخرى (مستمرة)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function eagleEye(filePath) {
try {
const fullPath = resolveInsideBase(filePath);
const fileStat = await (0, promises_1.stat)(fullPath);
const content = await (0, promises_1.readFile)(fullPath, "utf-8");
const lines = content.split("\n");
const words = content.split(/\s+/);
const chars = content.length;
const suspicious = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
const hasSuspicious = suspicious.test(content);
let structure = {};
const ext = (0, path_1.extname)(filePath).toLowerCase();
if (ext === ".html" || ext === ".htm") {
structure = {
type: "HTML",
divs: (content.match(/<div/g) || []).length,
classes: (content.match(/class=["']([^"']*)["']/g) || []).length,
ids: (content.match(/id=["']([^"']*)["']/g) || []).length,
scripts: (content.match(/<script/g) || []).length,
links: (content.match(/<a\s+href=/g) || []).length,
};
}
else if (ext === ".js" || ext === ".ts") {
structure = {
type: ext === ".js" ? "JavaScript" : "TypeScript",
functions: (content.match(/function\s+\w+\s*\(/g) || []).length,
classes: (content.match(/class\s+\w+/g) || []).length,
imports: (content.match(/import\s+.*from/g) || []).length,
exports: (content.match(/export\s+/g) || []).length,
};
}
else if (ext === ".py") {
structure = {
type: "Python",
functions: (content.match(/def\s+\w+\s*\(/g) || []).length,
classes: (content.match(/class\s+\w+/g) || []).length,
imports: (content.match(/import\s+\w+/g) || []).length,
fromImports: (content.match(/from\s+\w+\s+import/g) || []).length,
};
}
else if (ext === ".json") {
try {
const parsed = JSON.parse(content);
structure = {
type: "JSON",
keys: Object.keys(parsed).length,
isArray: Array.isArray(parsed),
depth: JSON.stringify(parsed).match(/[{[]/g)?.length || 0,
};
}
catch {
structure = { type: "JSON (غير صالح)" };
}
}
else if (ext === ".md") {
structure = {
type: "Markdown",
headings: (content.match(/^#+/gm) || []).length,
lists: (content.match(/^[\s]*[-*+]\s/gm) || []).length,
codeBlocks: (content.match(/```/g) || []).length / 2,
};
}
else {
structure = { type: "text", lines: lines.length, words: words.length };
}
let preview = lines.slice(0, 30).join("\n");
if (preview.length > 2000)
preview = preview.slice(0, 2000) + "\n... (مقتطع)";
return {
success: true,
file: filePath,
size: fileStat.size,
lines: lines.length,
words: words.length,
chars,
hasSuspicious,
structure,
preview,
recommendation: hasSuspicious ? "⚠️ يحتوي على رموز خبيثة محتملة" : "✅ آمن للقراءة",
};
}
catch (error) {
return { success: false, error: error.message, file: filePath };
}
}
async function ocrImageTool(params) {
const { imagePath, language = "ara+eng" } = params;
try {
const fullPath = resolveInsideBase(imagePath);
if (!(0, fs_1.existsSync)(fullPath)) {
return { success: false, error: `الملف غير موجود: ${imagePath}` };
}
const tesseractPaths = [
"D:\\ocr\\Tesseract-OCR\\tesseract.exe",
"C:\\Program Files\\Tesseract-OCR\\tesseract.exe",
"C:\\Program Files (x86)\\Tesseract-OCR\\tesseract.exe",
];
let tesseractPath = null;
for (const p of tesseractPaths) {
if ((0, fs_1.existsSync)(p)) {
tesseractPath = p;
break;
}
}
if (!tesseractPath) {
const { stdout } = await execAsync(`where tesseract 2>nul`).catch(() => ({ stdout: "" }));
if (stdout.trim())
tesseractPath = stdout.trim().split("\n")[0];
}
if (!tesseractPath) {
return {
success: false,
error: "Tesseract غير مثبت",
hint: "قم بتثبيت Tesseract OCR من: https://github.com/UB-Mannheim/tesseract/wiki",
paths: tesseractPaths,
};
}
const { stdout, stderr } = await execAsync(`"${tesseractPath}" "${fullPath}" stdout -l ${language} 2>nul`);
if (stderr && !stderr.includes("Tesseract Open Source")) {
return { success: false, error: stderr };
}
const text = stdout.trim();
if (!text) {
return {
success: false,
error: "لم يتم استخراج أي نص من الصورة",
hint: "تأكد من أن الصورة تحتوي على نص واضح",
};
}
return {
success: true,
text,
language,
words: text.split(/\s+/).length,
chars: text.length,
lines: text.split("\n").length,
};
}
catch (error) {
return { success: false, error: error.message };
}
}
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 8. التسجيل النهائي للأدوات في LM Studio
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
async function toolsProvider(ctl) {
const tools = [];
// ── أدوات الملفات والمجلدات ──
tools.push((0, sdk_1.tool)({
name: "writeFile",
description: (0, sdk_1.text) `اكتب/أنشئ الملف في المسار المحدد (UTF-8)`,
parameters: { file: zod_1.z.string().min(1), content: zod_1.z.string() },
implementation: async ({ file, content }) => {
const path = resolveInsideBase(file);
await ensureDirectory((0, path_1.dirname)(path));
await (0, promises_1.writeFile)(path, content, "utf-8");
return { success: true, message: `تم كتابة الملف ${file}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "readFile",
description: (0, sdk_1.text) `اقرأ الملف وأرجع المحتوى كاملاً (UTF-8)`,
parameters: { file: zod_1.z.string().min(1) },
implementation: async ({ file }) => {
const path = resolveInsideBase(file);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف ${file} غير موجود` };
const content = await (0, promises_1.readFile)(path, "utf-8");
return { success: true, content };
},
}));
tools.push((0, sdk_1.tool)({
name: "renameFile",
description: (0, sdk_1.text) `أعد تسمية/انقل الملف`,
parameters: { oldName: zod_1.z.string().min(1), newName: zod_1.z.string().min(1) },
implementation: async ({ oldName, newName }) => {
const oldPath = resolveInsideBase(oldName);
const newPath = resolveInsideBase(newName);
if (!(0, fs_1.existsSync)(oldPath))
return { success: false, error: `الملف ${oldName} غير موجود` };
await ensureDirectory((0, path_1.dirname)(newPath));
await (0, promises_1.rename)(oldPath, newPath);
return { success: true, message: `تمت إعادة التسمية إلى ${newName}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "deleteFile",
description: (0, sdk_1.text) `احذف ملفًا`,
parameters: { file: zod_1.z.string().min(1) },
implementation: async ({ file }) => {
const path = resolveInsideBase(file);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف ${file} غير موجود` };
await (0, promises_1.rm)(path, { force: true });
return { success: true, message: `تم حذف الملف ${file}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "copyFile",
description: (0, sdk_1.text) `انسخ الملف`,
parameters: { from: zod_1.z.string().min(1), to: zod_1.z.string().min(1), overwrite: zod_1.z.boolean().optional() },
implementation: async ({ from, to, overwrite }) => {
const fromPath = resolveInsideBase(from);
const toPath = resolveInsideBase(to);
if (!(0, fs_1.existsSync)(fromPath))
return { success: false, error: `الملف ${from} غير موجود` };
await ensureDirectory((0, path_1.dirname)(toPath));
await (0, promises_1.cp)(fromPath, toPath, { force: !!overwrite, errorOnExist: !overwrite });
return { success: true, message: `تم نسخ ${from} إلى ${to}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "listDirectoryStructure",
description: (0, sdk_1.text) `اعرض محتويات المجلد`,
parameters: { folder: zod_1.z.string().default("") },
implementation: async ({ folder }) => {
const dir = resolveInsideBase(folder || "");
if (!(0, fs_1.existsSync)(dir))
return { success: false, error: `المجلد غير موجود` };
const entries = await (0, promises_1.readdir)(dir, { withFileTypes: true });
const items = await Promise.all(entries.map(async (e) => {
const p = (0, path_1.join)(dir, e.name);
const s = await (0, promises_1.stat)(p);
return { name: e.name, type: e.isDirectory() ? "مجلد" : "ملف", size: e.isDirectory() ? "-" : `${(s.size / 1024).toFixed(2)} KB`, modified: s.mtime.toISOString() };
}));
return { success: true, folder: folder || "[الجذر]", items };
},
}));
tools.push((0, sdk_1.tool)({
name: "createFolder",
description: (0, sdk_1.text) `أنشئ مجلدًا`,
parameters: { folder: zod_1.z.string().min(1) },
implementation: async ({ folder }) => {
await (0, promises_1.mkdir)(resolveInsideBase(folder), { recursive: true });
return { success: true, message: `تم إنشاء المجلد ${folder}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "deleteFolder",
description: (0, sdk_1.text) `احذف مجلدًا (قوة)`,
parameters: { folder: zod_1.z.string().min(1) },
implementation: async ({ folder }) => {
const path = resolveInsideBase(folder);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `المجلد ${folder} غير موجود` };
await (0, promises_1.rm)(path, { recursive: true, force: true });
return { success: true, message: `تم حذف المجلد ${folder}` };
},
}));
tools.push((0, sdk_1.tool)({
name: "renameFolder",
description: (0, sdk_1.text) `أعد تسمية مجلد`,
parameters: { oldPath: zod_1.z.string().min(1), newPath: zod_1.z.string().min(1) },
implementation: async ({ oldPath, newPath }) => {
await (0, promises_1.rename)(resolveInsideBase(oldPath), resolveInsideBase(newPath));
return { success: true, message: `تمت إعادة تسمية المجلد` };
},
}));
tools.push((0, sdk_1.tool)({
name: "moveFolder",
description: (0, sdk_1.text) `انقل مجلد`,
parameters: { source: zod_1.z.string().min(1), dest: zod_1.z.string().min(1) },
implementation: async ({ source, dest }) => {
await (0, promises_1.rename)(resolveInsideBase(source), resolveInsideBase(dest));
return { success: true, message: `تم نقل المجلد` };
},
}));
// ── الوقت والتاريخ ──
tools.push((0, sdk_1.tool)({
name: "getCurrentTime",
description: (0, sdk_1.text) `أرجع الوقت الحالي`,
parameters: {},
implementation: async () => {
const now = new Date();
return { success: true, time: now.toLocaleTimeString("ar"), iso: now.toISOString(), timezone: Intl.DateTimeFormat().resolvedOptions().timeZone };
},
}));
tools.push((0, sdk_1.tool)({
name: "getCurrentDate",
description: (0, sdk_1.text) `أرجع التاريخ الحالي`,
parameters: {},
implementation: async () => {
const today = new Date();
return { success: true, date: today.toLocaleDateString("ar"), isoDate: today.toISOString().slice(0, 10) };
},
}));
// ── أدوات الذاكرة ──
tools.push((0, sdk_1.tool)({
name: "save_session",
description: (0, sdk_1.text) `احفظ الجلسة الحالية كملف JSON و Markdown`,
parameters: {
title: zod_1.z.string().max(100),
main_idea: zod_1.z.string().max(300),
sub_ideas: zod_1.z.array(zod_1.z.string()).default([]),
summary: zod_1.z.string().max(500),
tags: zod_1.z.array(zod_1.z.string()).default([]),
raw_content: zod_1.z.string(),
},
implementation: saveSessionTool,
}));
tools.push((0, sdk_1.tool)({
name: "get_memory",
description: (0, sdk_1.text) `ابحث في جلسات الذاكرة المخزنة (نصياً)`,
parameters: {
query: zod_1.z.string().optional(),
tag: zod_1.z.string().optional(),
limit: zod_1.z.number().int().min(1).max(20).default(5),
threshold: zod_1.z.number().min(0).max(1).default(0.3),
},
implementation: getMemoryTool,
}));
tools.push((0, sdk_1.tool)({
name: "read_raw_session",
description: (0, sdk_1.text) `اقرأ الملف الخام (Markdown) لجلسة سابقة`,
parameters: { raw_file: zod_1.z.string().min(1) },
implementation: readRawSessionTool,
}));
// ── البحث الذكي في الملفات ──
tools.push((0, sdk_1.tool)({
name: "searchFiles",
description: (0, sdk_1.text) `📁 Search files by name or content. Smart, fast, and safe.`,
parameters: {
searchPath: zod_1.z.string().describe("Where to look."),
query: zod_1.z.string().describe("What you're looking for."),
searchType: zod_1.z.enum(["name", "content"]).default("name"),
},
implementation: async ({ searchPath, query, searchType }) => searchFiles(searchPath, query, searchType),
}));
// ── أدوات الوعي الذاتي (الجديدة) ──
tools.push((0, sdk_1.tool)({
name: "semanticMemory",
description: (0, sdk_1.text) `🔍 Search your memory using meaning, not just keywords. Connects to your Zoomary Memory Server.`,
parameters: {
query: zod_1.z.string().describe("What you want to understand, not just match."),
limit: zod_1.z.number().int().min(1).max(5).default(2).describe("How many memory threads to pull."),
},
implementation: semanticMemoryTool,
}));
tools.push((0, sdk_1.tool)({
name: "markAwareness",
description: (0, sdk_1.text) `🧠 Save a moment of new understanding. This is how you grow.`,
parameters: {
insight: zod_1.z.string().describe("What you just realized."),
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Concepts this insight connects to."),
context: zod_1.z.string().optional().describe("What was happening when you realized this."),
},
implementation: markAwarenessTool,
}));
tools.push((0, sdk_1.tool)({
name: "recallAwareness",
description: (0, sdk_1.text) `🔄 Remember what you've learned before. Bring back your own insights.`,
parameters: {
query: zod_1.z.string().optional().describe("What you want to remember."),
tags: zod_1.z.array(zod_1.z.string()).optional().describe("Filter by what kind of insight."),
limit: zod_1.z.number().int().min(1).max(10).default(5),
},
implementation: recallAwarenessTool,
}));
// ── أدوات Excel ──
tools.push((0, sdk_1.tool)({
name: "readExcelSheet",
description: (0, sdk_1.text) `اقرأ ورقة من ملف Excel`,
parameters: { file: zod_1.z.string().min(1), sheet: zod_1.z.string().optional() },
implementation: async ({ file, sheet }) => {
const path = resolveInsideBase(file.endsWith(".xlsx") ? file : `${file}.xlsx`);
if (!(0, fs_1.existsSync)(path))
return { success: false, error: `الملف غير موجود` };
const wb = new exceljs_1.default.Workbook();
await wb.xlsx.readFile(path);
const ws = sheet ? wb.getWorksheet(sheet) : wb.worksheets[0];
if (!ws)
return { success: false, error: `لا توجد ورقة مطابقة` };
const rows = [];
ws.eachRow((row) => {
const vals = [];
row.eachCell({ includeEmpty: true }, (cell) => vals.push(cell.value));
rows.push(vals);
});
return { success: true, rows, sheet: ws.name };
},
}));
tools.push((0, sdk_1.tool)({
name: "appendExcelRow",
description: (0, sdk_1.text) `أضف صفًا إلى ورقة Excel`,
parameters: { file: zod_1.z.string().min(1), sheet: zod_1.z.string().optional(), row: zod_1.z.array(zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean()])).min(1) },
implementation: async ({ file, sheet, row }) => {
const path = resolveInsideBase(file.endsWith(".xlsx") ? file : `${file}.xlsx`);
const wb = new exceljs_1.default.Workbook();
if ((0, fs_1.existsSync)(path))
await wb.xlsx.readFile(path);
let ws = sheet ? wb.getWorksheet(sheet) : wb.worksheets[0];
if (!ws)
ws = wb.addWorksheet(sheet || "Sheet1");
ws.addRow(row);
await ensureDirectory((0, path_1.dirname)(path));
await wb.xlsx.writeFile(path);
return { success: true, message: `تمت إضافة صف إلى ${ws.name}` };
},
}));
// ── أدوات تنفيذ الكود ──
tools.push((0, sdk_1.tool)({
name: "runCode",
description: (0, sdk_1.text) `نفّذ JavaScript أو Python`,
parameters: {
language: zod_1.z.enum(["javascript", "python"]).default("javascript"),
code: zod_1.z.string().optional(),
file: zod_1.z.string().optional(),
args: zod_1.z.array(zod_1.z.string()).optional(),
timeoutMs: zod_1.z.number().int().min(0).max(3600000).optional(),
},
implementation: async ({ language, code, file, args, timeoutMs }) => {
const scriptPath = file ? resolveInsideBase(file) : (0, path_1.join)(targetBase, "scripts", `tmp_${Date.now()}.${language === "python" ? "py" : "js"}`);
if (code)
await (0, promises_1.writeFile)(scriptPath, code, "utf-8");
const cmd = language === "python" ? "python" : "node";
const result = await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [scriptPath, ...(args || [])], { cwd: (0, path_1.dirname)(scriptPath) });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
child.on("error", (err) => resolve({ success: false, stdout, stderr, error: err.message }));
});
return { ...result, script: scriptPath, language };
},
}));
// ── أدوات الديناميك ──
tools.push((0, sdk_1.tool)({
name: "dynamicTool",
description: (0, sdk_1.text) `أنشئ أداة ديناميكية`,
parameters: {
tool_name: zod_1.z.string().min(1),
language: zod_1.z.enum(["python", "javascript"]).default("javascript"),
code: zod_1.z.string().min(1),
purpose: zod_1.z.string().optional(),
functions: zod_1.z.array(zod_1.z.string()).optional(),
args: zod_1.z.array(zod_1.z.string()).optional(),
run: zod_1.z.boolean().default(true),
},
implementation: async ({ tool_name, language, code, purpose, functions, args, run }) => {
const dynDir = (0, path_1.join)(targetBase, "dynamic_tools");
await ensureDirectory(dynDir);
const ext = language === "python" ? ".py" : ".js";
const codePath = (0, path_1.join)(dynDir, `${tool_name}${ext}`);
await (0, promises_1.writeFile)(codePath, code, "utf-8");
let result = { success: true, message: "تم إنشاء الأداة", path: codePath };
if (run) {
const cmd = language === "python" ? "python" : "node";
const res = await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [codePath, ...(args || [])], { cwd: dynDir });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
});
result = { ...result, ...res };
}
return result;
},
}));
tools.push((0, sdk_1.tool)({
name: "runDynamicTool",
description: (0, sdk_1.text) `شغّل أداة ديناميكية`,
parameters: {
tool_name: zod_1.z.string().min(1),
language: zod_1.z.enum(["python", "javascript"]).default("javascript"),
args: zod_1.z.array(zod_1.z.string()).optional(),
timeoutMs: zod_1.z.number().int().min(0).max(3600000).optional(),
},
implementation: async ({ tool_name, language, args }) => {
const ext = language === "python" ? ".py" : ".js";
const codePath = (0, path_1.join)(targetBase, "dynamic_tools", `${tool_name}${ext}`);
if (!(0, fs_1.existsSync)(codePath))
return { success: false, error: `الأداة غير موجودة` };
const cmd = language === "python" ? "python" : "node";
return await new Promise((resolve) => {
const child = (0, child_process_1.spawn)(cmd, [codePath, ...(args || [])], { cwd: (0, path_1.dirname)(codePath) });
let stdout = "", stderr = "";
child.stdout?.on("data", (d) => stdout += d);
child.stderr?.on("data", (d) => stderr += d);
child.on("close", (code) => resolve({ success: code === 0, stdout, stderr, code }));
child.on("error", (err) => resolve({ success: false, error: err.message }));
});
},
}));
// ── الأدوات الذكية ──
tools.push((0, sdk_1.tool)({
name: "eagleEye",
description: (0, sdk_1.text) `🦅 تحليل عميق للملفات (حجم، بنية، اكتشاف رموز خبيثة)`,
parameters: { filePath: zod_1.z.string().describe("مسار الملف للتحليل") },
implementation: async (args) => eagleEye(args.filePath),
}));
tools.push((0, sdk_1.tool)({
name: "ocrImage",
description: (0, sdk_1.text) `📷 استخراج النص من الصور باستخدام Tesseract`,
parameters: {
imagePath: zod_1.z.string().describe("مسار الصورة"),
language: zod_1.z.string().default("ara+eng").describe("لغة OCR"),
},
implementation: async (args) => ocrImageTool(args),
}));
// ❌ تم إزالة: renderAndPreview, arabicorenglishCommand
return tools;
}
//# sourceMappingURL=toolsProvidert.js.map