humanbehavior-js
Version:
SDK for HumanBehavior session and event recording
240 lines (214 loc) • 8.83 kB
text/typescript
/**
* Remote AI Service Implementation
*
* This connects to your deployed Lambda function via API Gateway
*/
import { AICodeAnalysis } from '../ai/ai-install-wizard';
export interface FrameworkInfo {
name: string;
type: 'react' | 'vue' | 'angular' | 'svelte' | 'nextjs' | 'nuxt' | 'remix' | 'vanilla' | 'astro' | 'gatsby' | 'node';
bundler?: 'vite' | 'webpack' | 'esbuild' | 'rollup';
packageManager?: 'npm' | 'yarn' | 'pnpm';
hasTypeScript?: boolean;
hasRouter?: boolean;
projectRoot?: string;
version?: string;
majorVersion?: number;
features?: {
hasReact18?: boolean;
hasVue3?: boolean;
hasNuxt3?: boolean;
hasAngularStandalone?: boolean;
hasNextAppRouter?: boolean;
hasSvelteKit?: boolean;
};
}
export interface RemoteAIServiceConfig {
apiEndpoint: string;
timeout?: number;
}
export class RemoteAIService {
private config: RemoteAIServiceConfig;
constructor(config: RemoteAIServiceConfig) {
this.config = {
timeout: 10000, // 10 seconds
...config
};
}
/**
* Analyze code patterns using your deployed AI service
*/
async analyzeCodePatterns(codeSamples: string[]): Promise<AICodeAnalysis> {
try {
const response = await fetch(`${this.config.apiEndpoint}/analyze`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ codeSamples }),
signal: AbortSignal.timeout(this.config.timeout || 10000)
});
if (!response.ok) {
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
}
const result = await response.json();
return result.analysis;
} catch (error) {
console.warn('Remote AI service failed, falling back to heuristic analysis:', error);
return this.performHeuristicAnalysis(codeSamples);
}
}
/**
* Resolve conflicts using your deployed AI service
*/
async resolveConflicts(conflicts: string[], framework: FrameworkInfo): Promise<string[]> {
try {
const response = await fetch(`${this.config.apiEndpoint}/resolve-conflicts`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ conflicts, framework }),
signal: AbortSignal.timeout(this.config.timeout || 10000)
});
if (!response.ok) {
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
}
const result = await response.json();
return result.resolutions || [];
} catch (error) {
console.warn('Remote AI conflict resolution failed, using heuristic approach:', error);
return this.resolveConflictsHeuristic(conflicts, framework);
}
}
/**
* Generate optimizations using your deployed AI service
*/
async generateOptimizations(framework: FrameworkInfo, patterns: string[]): Promise<string[]> {
try {
const response = await fetch(`${this.config.apiEndpoint}/optimize`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ framework, patterns }),
signal: AbortSignal.timeout(this.config.timeout || 10000)
});
if (!response.ok) {
throw new Error(`AI service returned ${response.status}: ${response.statusText}`);
}
const result = await response.json();
return result.optimizations || [];
} catch (error) {
console.warn('Remote AI optimization generation failed, using heuristic approach:', error);
return this.generateOptimizationsHeuristic(framework, patterns);
}
}
/**
* Heuristic analysis fallback
*/
private performHeuristicAnalysis(codeSamples: string[]): AICodeAnalysis {
const patterns = codeSamples.join(' ').toLowerCase();
// Framework detection
let framework: FrameworkInfo = { name: 'vanilla', type: 'vanilla' };
let confidence = 0.5;
if (patterns.includes('nuxt') || patterns.includes('nuxtjs') || patterns.includes('defineNuxtConfig') || patterns.includes('nuxt.config') || patterns.includes('@nuxt/') || patterns.includes('useNuxtApp') || patterns.includes('useRuntimeConfig') || patterns.includes('useSeoMeta') || patterns.includes('useHead') || patterns.includes('useLazyFetch') || patterns.includes('useFetch') || patterns.includes('useAsyncData') || patterns.includes('#app')) {
framework = { name: 'nuxt', type: 'nuxt' };
confidence = 0.95;
} else if (patterns.includes('next') || patterns.includes('nextjs') || patterns.includes('next/link') || patterns.includes('next/image') || patterns.includes('next/navigation') || patterns.includes('next/router') || patterns.includes('getserverSideProps') || patterns.includes('getstaticProps') || patterns.includes('getstaticPaths') || patterns.includes('app/layout') || patterns.includes('app/page') || patterns.includes('pages/')) {
framework = { name: 'nextjs', type: 'nextjs' };
confidence = 0.95;
} else if (patterns.includes('gatsby') || patterns.includes('gatsby-browser') || patterns.includes('gatsby-ssr') || patterns.includes('gatsby-node') || patterns.includes('gatsby-config') || patterns.includes('useStaticQuery') || patterns.includes('graphql')) {
framework = { name: 'gatsby', type: 'gatsby' };
confidence = 0.95;
} else if (patterns.includes('react')) {
framework = { name: 'react', type: 'react' };
confidence = 0.9;
} else if (patterns.includes('vue')) {
framework = { name: 'vue', type: 'vue' };
confidence = 0.9;
} else if (patterns.includes('angular')) {
framework = { name: 'angular', type: 'angular' };
confidence = 0.9;
} else if (patterns.includes('svelte')) {
framework = { name: 'svelte', type: 'svelte' };
confidence = 0.9;
} else if (patterns.includes('astro')) {
framework = { name: 'astro', type: 'astro' };
confidence = 0.9;
}
// Integration strategy
let integrationStrategy: 'provider' | 'plugin' | 'module' | 'script' | 'standalone' = 'script';
if (framework.type === 'react' || framework.type === 'nextjs' || framework.type === 'gatsby') {
integrationStrategy = 'provider';
} else if (framework.type === 'vue') {
integrationStrategy = 'plugin';
} else if (framework.type === 'angular') {
integrationStrategy = 'module';
}
// Compatibility mode
let compatibilityMode: 'modern' | 'legacy' | 'hybrid' = 'modern';
if (patterns.includes('require(') || patterns.includes('var ')) {
compatibilityMode = 'legacy';
}
return {
framework,
confidence,
patterns: codeSamples,
conflicts: [],
recommendations: [],
integrationStrategy,
compatibilityMode
};
}
/**
* Heuristic conflict resolution
*/
private resolveConflictsHeuristic(conflicts: string[], framework: FrameworkInfo): string[] {
const resolutions: string[] = [];
for (const conflict of conflicts) {
switch (conflict) {
case 'existing_humanbehavior_code':
resolutions.push('update_existing_integration');
break;
case 'existing_provider':
resolutions.push('merge_providers');
break;
case 'module_system_conflict':
resolutions.push('hybrid_module_support');
break;
default:
resolutions.push('skip_conflict');
}
}
return resolutions;
}
/**
* Heuristic optimization generation
*/
private generateOptimizationsHeuristic(framework: FrameworkInfo, patterns: string[]): string[] {
const optimizations: string[] = [];
switch (framework.type) {
case 'react':
optimizations.push('Use React.memo for performance optimization');
optimizations.push('Implement error boundaries for better error tracking');
optimizations.push('Consider using React.lazy for code splitting');
break;
case 'vue':
optimizations.push('Use Vue 3 Composition API for better performance');
optimizations.push('Implement proper error handling in components');
optimizations.push('Consider using Vue Router for navigation tracking');
break;
case 'angular':
optimizations.push('Use Angular standalone components for better tree-shaking');
optimizations.push('Implement proper error handling with ErrorHandler');
optimizations.push('Consider using Angular signals for state management');
break;
default:
optimizations.push('Enable performance tracking');
optimizations.push('Implement error tracking');
optimizations.push('Consider progressive enhancement');
}
return optimizations;
}
}