From 1e1a978472438ba8fb15b36e11d6efa4f52e4115 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 18:59:19 +0000 Subject: [PATCH] Add OpenAI API integration for error analysis with settings UI Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com> --- .github/workflows/deploy-pages.yml | 2 +- src/app/settings/page.tsx | 3 + src/components/error/analyzeError.ts | 96 +++++++++++++--- .../settings/OpenAISettingsCard.tsx | 107 ++++++++++++++++++ 4 files changed, 192 insertions(+), 16 deletions(-) create mode 100644 src/components/settings/OpenAISettingsCard.tsx diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index b58e0ff..7151d43 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -32,7 +32,7 @@ jobs: run: npm ci - name: Build Next.js - run: npm run build -- --webpack + run: npm run build env: BUILD_STATIC: 'true' NEXT_PUBLIC_FLASK_BACKEND_URL: ${{ vars.NEXT_PUBLIC_FLASK_BACKEND_URL || '' }} diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 55d950e..82ca29f 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -8,6 +8,7 @@ import { StorageBackendCard } from '@/components/settings/StorageBackendCard'; import { DatabaseStatsCard } from '@/components/settings/DatabaseStatsCard'; import { StorageInfoCard } from '@/components/settings/StorageInfoCard'; import { DatabaseActionsCard } from '@/components/settings/DatabaseActionsCard'; +import { OpenAISettingsCard } from '@/components/settings/OpenAISettingsCard'; import { useSettingsState } from '@/hooks/useSettingsState'; import { PageLayout } from '../PageLayout'; @@ -50,6 +51,8 @@ export default function SettingsPage() {
+ + { - // Simple error analysis without AI - just return helpful debugging info - const lines = ['## Error Analysis\n']; + // Check if OpenAI API key is configured + const apiKey = localStorage.getItem('openai_api_key'); - lines.push('**Error Message:**'); - lines.push(`\`${errorMessage}\`\n`); - - if (context) { - lines.push('**Context:**'); - lines.push(`${context}\n`); - } - - if (errorStack) { - lines.push('**Possible Solutions:**'); + if (!apiKey) { + // Fallback to simple error analysis if no API key + const lines = ['## Error Analysis\n']; + + lines.push('**Error Message:**'); + lines.push(`\`${errorMessage}\`\n`); + + if (context) { + lines.push('**Context:**'); + lines.push(`${context}\n`); + } + + lines.push('**Note:** Configure your OpenAI API key in Settings to enable AI-powered error analysis.\n'); + + lines.push('**Basic Troubleshooting:**'); lines.push('1. Check the browser console for more details'); lines.push('2. Try refreshing the page'); - lines.push('3. Clear your browser cache and local storage\n'); + lines.push('3. Clear your browser cache and local storage'); + + return lines.join('\n'); + } + + // Use OpenAI API for advanced error analysis + try { + const contextInfo = context ? `\n\nContext: ${context}` : ''; + const stackInfo = errorStack ? `\n\nStack trace: ${errorStack}` : ''; + + const prompt = `You are a helpful debugging assistant for a code snippet manager app. Analyze this error and provide: + +1. A clear explanation of what went wrong (in plain language) +2. Why this error likely occurred +3. 2-3 specific actionable steps to fix it + +Error message: ${errorMessage}${contextInfo}${stackInfo} + +Keep your response concise, friendly, and focused on practical solutions. Format your response with clear sections using markdown.`; + + const response = await fetch('https://api.openai.com/v1/chat/completions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${apiKey}`, + }, + body: JSON.stringify({ + model: 'gpt-4o-mini', + messages: [ + { + role: 'system', + content: 'You are a helpful debugging assistant for a code snippet manager app.', + }, + { + role: 'user', + content: prompt, + }, + ], + temperature: 0.7, + max_tokens: 500, + }), + }); + + if (!response.ok) { + throw new Error(`OpenAI API error: ${response.status} ${response.statusText}`); + } + + const data = await response.json(); + return data.choices[0]?.message?.content || 'Unable to analyze error.'; + } catch (err) { + console.error('Error calling OpenAI API:', err); + + // Fallback to simple analysis if API call fails + return `## Error Analysis + +**Error Message:** +\`${errorMessage}\` + +**Note:** Failed to get AI analysis. ${err instanceof Error ? err.message : 'Unknown error'} + +**Basic Troubleshooting:** +1. Check the browser console for more details +2. Try refreshing the page +3. Verify your OpenAI API key in Settings`; } - - return lines.join('\n'); } diff --git a/src/components/settings/OpenAISettingsCard.tsx b/src/components/settings/OpenAISettingsCard.tsx new file mode 100644 index 0000000..d8a8ff2 --- /dev/null +++ b/src/components/settings/OpenAISettingsCard.tsx @@ -0,0 +1,107 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; +import { Label } from '@/components/ui/label'; +import { Eye, EyeClosed, Key } from '@phosphor-icons/react'; + +export function OpenAISettingsCard() { + const [apiKey, setApiKey] = useState(''); + const [showKey, setShowKey] = useState(false); + const [saved, setSaved] = useState(false); + + useEffect(() => { + // Load the API key from localStorage on mount + const storedKey = localStorage.getItem('openai_api_key'); + if (storedKey) { + setApiKey(storedKey); + } + }, []); + + const handleSave = () => { + if (apiKey.trim()) { + localStorage.setItem('openai_api_key', apiKey.trim()); + setSaved(true); + setTimeout(() => setSaved(false), 2000); + } else { + localStorage.removeItem('openai_api_key'); + setSaved(true); + setTimeout(() => setSaved(false), 2000); + } + }; + + const handleClear = () => { + setApiKey(''); + localStorage.removeItem('openai_api_key'); + setSaved(true); + setTimeout(() => setSaved(false), 2000); + }; + + return ( + + +
+ + OpenAI API Settings +
+ + Configure your OpenAI API key for AI-powered error analysis. Your key is stored locally in your browser. + +
+ +
+ +
+
+ setApiKey(e.target.value)} + placeholder="sk-..." + className="pr-10" + /> + +
+
+

+ Get your API key from{' '} + + OpenAI Platform + +

+
+ +
+ + {apiKey && ( + + )} +
+ + {apiKey && ( +
+ ✓ API key is configured. Error analysis will use OpenAI GPT-4. +
+ )} +
+
+ ); +}