ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
251 lines • 9.32 kB
JavaScript
export class AIStackDetector {
llmPatterns = {
OpenAI: {
urlPattern: /api\.openai\.com\/v\d+/,
endpoints: ['chat/completions', 'completions', 'embeddings', 'images/generations'],
modelExtractor: (body) => {
if (typeof body === 'string') {
try {
body = JSON.parse(body);
}
catch {
return [];
}
}
return body.model ? [body.model] : [];
}
},
Anthropic: {
urlPattern: /api\.anthropic\.com\/v\d+/,
endpoints: ['messages', 'complete'],
modelExtractor: (body) => {
if (typeof body === 'string') {
try {
body = JSON.parse(body);
}
catch {
return [];
}
}
return body.model ? [body.model] : [];
}
},
Google: {
urlPattern: /generativelanguage\.googleapis\.com|aiplatform\.googleapis\.com/,
endpoints: ['models', 'generateContent'],
modelExtractor: (body) => {
if (typeof body === 'string') {
try {
body = JSON.parse(body);
}
catch {
return [];
}
}
return body.model ? [body.model] : [];
}
}
};
vectorDBPatterns = {
Pinecone: {
urlPattern: /\.pinecone\.io\/(query|upsert|delete|fetch|update)/,
extractInfo: (url) => {
// Example: https://my-index-123.svc.us-west1-gcp.pinecone.io/query
const match = url.match(/https?:\/\/([^.]+)\.svc\.([^.]+)\.pinecone\.io/);
if (match) {
return {
indexName: match[1],
region: match[2]
};
}
return {};
}
},
Weaviate: {
urlPattern: /\/v1\/objects|\/v1\/batch|\/v1\/graphql/,
extractInfo: () => ({})
},
Qdrant: {
urlPattern: /\/collections\/[^/]+\/(points|search)/,
extractInfo: () => ({})
},
ChromaDB: {
urlPattern: /\/api\/v1\/collections/,
extractInfo: () => ({})
},
pgvector: {
sqlPattern: /<->|<=>|<#>/,
extractInfo: () => ({ database: 'PostgreSQL' })
}
};
async detectLLMProviders(engine) {
const providers = new Map();
const networkRequests = engine.getNetworkRequests();
for (const request of networkRequests) {
for (const [name, pattern] of Object.entries(this.llmPatterns)) {
if (pattern.urlPattern.test(request.url)) {
const existingProvider = providers.get(name) || {
name,
version: this.extractVersion(request.url),
models: [],
endpoints: []
};
const models = pattern.modelExtractor(request.requestBody);
const endpoint = request.url;
existingProvider.models = [...new Set([...existingProvider.models, ...models])];
existingProvider.endpoints = [...new Set([...existingProvider.endpoints, endpoint])];
providers.set(name, existingProvider);
}
}
}
return Array.from(providers.values());
}
async detectVectorDBs(engine) {
const vectorDBs = new Map();
const networkRequests = engine.getNetworkRequests();
for (const request of networkRequests) {
// Check URL patterns
for (const [name, pattern] of Object.entries(this.vectorDBPatterns)) {
if ('urlPattern' in pattern && pattern.urlPattern.test(request.url)) {
const info = pattern.extractInfo(request.url);
const operation = this.extractVectorOperation(request.url);
const existingDB = vectorDBs.get(name) || {
name,
operations: [],
...info
};
if (operation) {
existingDB.operations = [...new Set([...existingDB.operations, operation])];
}
vectorDBs.set(name, existingDB);
}
}
// Check for pgvector SQL patterns
if (request.requestBody && typeof request.requestBody === 'string') {
const pgvectorPattern = this.vectorDBPatterns.pgvector;
if (pgvectorPattern.sqlPattern.test(request.requestBody)) {
vectorDBs.set('pgvector', {
name: 'pgvector',
database: 'PostgreSQL',
operations: ['similarity_search']
});
}
}
}
return Array.from(vectorDBs.values());
}
async detectFrameworks(page) {
const frameworks = [];
if (!page) {
return frameworks;
}
try {
const detection = await page.evaluate(() => {
const result = {};
// Check for LangChain
if (window.langchain || window.LangChain) {
result.hasLangChain = true;
result.langChainVersion = window.langchain?.version || '0.1.0';
}
// Check for LlamaIndex
if (window.llamaIndex || window.LlamaIndex) {
result.hasLlamaIndex = true;
result.llamaIndexVersion = window.llamaIndex?.version || '0.9.0';
}
// Check for other frameworks
if (window.openai) {
result.hasOpenAISDK = true;
}
return result;
});
if (detection.hasLangChain) {
frameworks.push({
name: 'LangChain',
version: detection.langChainVersion,
components: []
});
}
if (detection.hasLlamaIndex) {
frameworks.push({
name: 'LlamaIndex',
version: detection.llamaIndexVersion,
components: []
});
}
if (detection.hasOpenAISDK) {
frameworks.push({
name: 'OpenAI SDK',
version: 'unknown',
components: []
});
}
}
catch (error) {
// Failed to detect frameworks from page context
}
return frameworks;
}
async detectDocumentLoaders(engine) {
const loaders = [];
const seenTypes = new Set();
const networkRequests = engine.getNetworkRequests();
for (const request of networkRequests) {
const contentType = request.headers?.['Content-Type'] || request.headers?.['content-type'] || '';
let documentType = null;
// Check by content type
if (contentType.includes('pdf')) {
documentType = 'PDF';
}
else if (contentType.includes('wordprocessingml')) {
documentType = 'DOCX';
}
else if (contentType.includes('msword')) {
documentType = 'DOC';
}
else if (contentType.includes('csv')) {
documentType = 'CSV';
}
// Check by URL patterns
if (!documentType && request.url) {
if (/process-pdf|pdf-upload|extract-pdf/i.test(request.url)) {
documentType = 'PDF';
}
else if (/process-doc|doc-upload|docx-upload/i.test(request.url)) {
documentType = 'DOCX';
}
}
if (documentType && !seenTypes.has(documentType)) {
seenTypes.add(documentType);
loaders.push({
type: documentType,
endpoint: this.extractEndpoint(request.url),
method: 'API'
});
}
}
return loaders;
}
extractVersion(url) {
const match = url.match(/\/v(\d+)/);
return match ? `v${match[1]}` : 'v1';
}
extractVectorOperation(url) {
const operations = ['query', 'upsert', 'delete', 'fetch', 'update', 'search'];
for (const op of operations) {
if (url.includes(op)) {
return op;
}
}
return 'unknown';
}
extractEndpoint(url) {
try {
const urlObj = new URL(url);
return urlObj.pathname;
}
catch {
return url;
}
}
}
//# sourceMappingURL=ai-stack-detector.js.map