il2cpp-dump-analyzer-mcp
Version:
Agentic RAG system for analyzing IL2CPP dump.cs files from Unity games
213 lines • 7.57 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SimpleEmbeddings = void 0;
const embeddings_1 = require("@langchain/core/embeddings");
const crypto = __importStar(require("crypto"));
const compute_cosine_similarity_1 = __importDefault(require("compute-cosine-similarity"));
/**
* A simple embedding implementation that uses TF-IDF like approach
* with cosine similarity for retrieval.
*
* This is a lightweight alternative that doesn't require external models
* or native dependencies.
*/
class SimpleEmbeddings extends embeddings_1.Embeddings {
constructor() {
super({});
this.vocabulary = new Map();
this.documentVectors = new Map();
this.dimensions = 300; // Fixed dimension size
}
/**
* Create embeddings for an array of texts
* @param texts Array of texts to embed
* @returns Promise resolving to a 2D array of embeddings
*/
async embedDocuments(texts) {
// Build vocabulary from all texts
this.buildVocabulary(texts);
// Create vectors for each text
const vectors = [];
for (let i = 0; i < texts.length; i++) {
const text = texts[i];
const vector = this.textToVector(text);
// Store the vector for future similarity calculations
const docId = this.getDocumentId(text);
this.documentVectors.set(docId, vector);
vectors.push(vector);
}
return vectors;
}
/**
* Create an embedding for a single query text
* @param text Text to embed
* @returns Promise resolving to an embedding vector
*/
async embedQuery(text) {
return this.textToVector(text);
}
/**
* Get the dimensionality of the embeddings
* @returns The number of dimensions in the embedding vectors
*/
getDimension() {
return this.dimensions;
}
/**
* Find the most similar documents to a query
* @param query Query text
* @param k Number of results to return
* @returns Array of document IDs and similarity scores
*/
async findSimilarDocuments(query, k = 5) {
const queryVector = await this.embedQuery(query);
const results = [];
// Calculate similarity with each document
for (const [docId, docVector] of this.documentVectors.entries()) {
const similarity = (0, compute_cosine_similarity_1.default)(queryVector, docVector) || 0;
results.push([docId, similarity]);
}
// Sort by similarity (descending)
results.sort((a, b) => b[1] - a[1]);
// Return top k results
return results.slice(0, k);
}
/**
* Build vocabulary from texts
* @param texts Array of texts
*/
buildVocabulary(texts) {
const allWords = new Set();
// Collect all unique words
for (const text of texts) {
const words = this.tokenize(text);
for (const word of words) {
allWords.add(word);
}
}
// Assign index to each word
let index = 0;
for (const word of allWords) {
this.vocabulary.set(word, index);
index++;
}
}
/**
* Convert text to vector
* @param text Input text
* @returns Vector representation
*/
textToVector(text) {
const words = this.tokenize(text);
const wordCounts = new Map();
// Count word frequencies
for (const word of words) {
const count = wordCounts.get(word) || 0;
wordCounts.set(word, count + 1);
}
// Create a sparse vector
const sparseVector = new Map();
for (const [word, count] of wordCounts.entries()) {
const index = this.vocabulary.get(word);
if (index !== undefined) {
// TF-IDF like weighting
const tf = count / words.length;
const idf = Math.log(1 + this.vocabulary.size / (1 + this.getDocumentFrequency(word)));
sparseVector.set(index, tf * idf);
}
}
// Convert sparse vector to fixed-size vector using hashing
return this.hashVector(sparseVector);
}
/**
* Tokenize text into words
* @param text Input text
* @returns Array of tokens
*/
tokenize(text) {
// Simple tokenization: lowercase, remove punctuation, split by whitespace
return text
.toLowerCase()
.replace(/[^\w\s]/g, '')
.split(/\s+/)
.filter(word => word.length > 0);
}
/**
* Get document frequency for a word
* @param word Word to check
* @returns Number of documents containing the word
*/
getDocumentFrequency(word) {
// For simplicity, assume each word appears in one document
return 1;
}
/**
* Generate a unique ID for a document
* @param text Document text
* @returns Unique ID
*/
getDocumentId(text) {
return crypto.createHash('md5').update(text).digest('hex');
}
/**
* Convert sparse vector to fixed-size vector using hashing
* @param sparseVector Sparse vector
* @returns Fixed-size vector
*/
hashVector(sparseVector) {
const vector = new Array(this.dimensions).fill(0);
for (const [index, value] of sparseVector.entries()) {
// Use multiple hash functions to distribute values
for (let i = 0; i < 3; i++) {
const hashedIndex = (index * (i + 1)) % this.dimensions;
vector[hashedIndex] += value;
}
}
// Normalize the vector
const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
if (magnitude > 0) {
for (let i = 0; i < vector.length; i++) {
vector[i] /= magnitude;
}
}
return vector;
}
}
exports.SimpleEmbeddings = SimpleEmbeddings;
//# sourceMappingURL=simple-embeddings.js.map