error-solution-ai-buddy 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +291 -2
- package/backend/src/ai/ollama-service.js +264 -0
- package/backend/src/services/history-service.js +194 -0
- package/cli/error-listener.js +409 -0
- package/cli/formatter.js +244 -0
- package/cli/index.js +241 -0
- package/cli/package-lock.json +6 -0
- package/cli/package.json +3 -0
- package/package.json +53 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sithija Harshana Jayasinghe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,292 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Error → Solution AI Buddy 🤖
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> AI-powered error explanations directly in your terminal. No context switching!
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
## The Problem
|
|
10
|
+
|
|
11
|
+
You're coding. An error appears. You:
|
|
12
|
+
1. Copy the error
|
|
13
|
+
2. Open browser
|
|
14
|
+
3. Paste into Google/ChatGPT
|
|
15
|
+
4. Read through results
|
|
16
|
+
5. Go back to terminal
|
|
17
|
+
6. Forget what you were doing
|
|
18
|
+
|
|
19
|
+
**That's 5+ context switches. We fix that.**
|
|
20
|
+
|
|
21
|
+
## The Solution
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
$ errbuddy node app.js
|
|
25
|
+
|
|
26
|
+
TypeError: Cannot read properties of undefined (reading 'map')
|
|
27
|
+
at app.js:12:5
|
|
28
|
+
|
|
29
|
+
╭─ 🤖 Error Buddy Explanation: ─────────────────────────────────────╮
|
|
30
|
+
│ │
|
|
31
|
+
│ 📘 What is this? │
|
|
32
|
+
│ You tried to use `.map()` on a variable that is undefined. │
|
|
33
|
+
│ │
|
|
34
|
+
│ ❓ Why it happens? │
|
|
35
|
+
│ The data you expected (probably from an API) wasn't available. │
|
|
36
|
+
│ │
|
|
37
|
+
│ ✅ How to fix it: │
|
|
38
|
+
│ Check if the variable exists before calling `.map()`. │
|
|
39
|
+
│ │
|
|
40
|
+
│ 💡 Example: │
|
|
41
|
+
│ if (data) { │
|
|
42
|
+
│ data.map(...) │
|
|
43
|
+
│ } │
|
|
44
|
+
│ │
|
|
45
|
+
╰────────────────────────────────────────────────────────────────────╯
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick Start
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install -g error-solution-ai-buddy
|
|
52
|
+
errbuddy node app.js
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
That's it. Errors are explained with built-in pattern matching straight away.
|
|
56
|
+
|
|
57
|
+
### Turn on AI explanations (optional, free, runs on your machine)
|
|
58
|
+
|
|
59
|
+
errbuddy uses [Ollama](https://ollama.com) to run a small AI model locally, so your code and errors never leave your computer.
|
|
60
|
+
|
|
61
|
+
1. Install Ollama from https://ollama.com/download
|
|
62
|
+
2. Download the default model (about 400 MB):
|
|
63
|
+
```bash
|
|
64
|
+
ollama pull qwen2.5:0.5b
|
|
65
|
+
```
|
|
66
|
+
3. Make sure Ollama is running (`ollama serve`, or open the Ollama app)
|
|
67
|
+
|
|
68
|
+
Want better explanations? Use a bigger model: `errbuddy --model llama3.2 node app.js`
|
|
69
|
+
|
|
70
|
+
If Ollama isn't running, errbuddy still works — it falls back to pattern matching.
|
|
71
|
+
|
|
72
|
+
## Installation & Usage
|
|
73
|
+
|
|
74
|
+
### 1. Download the Project
|
|
75
|
+
- Clone the repository:
|
|
76
|
+
```sh
|
|
77
|
+
git clone <your-repo-url>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 2. Install Dependencies
|
|
81
|
+
- In the project folder, run:
|
|
82
|
+
```sh
|
|
83
|
+
npm install
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### 3. Use the CLI Tool
|
|
87
|
+
- Go to the CLI directory:
|
|
88
|
+
```sh
|
|
89
|
+
cd error-solution-ai-buddy/cli
|
|
90
|
+
npm link
|
|
91
|
+
```
|
|
92
|
+
- Now you can run the CLI from anywhere:
|
|
93
|
+
```sh
|
|
94
|
+
errbuddy <your-command>
|
|
95
|
+
# Example:
|
|
96
|
+
errbuddy node test-error.js
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 4. Use the VS Code Extension
|
|
100
|
+
- Build the extension (if needed):
|
|
101
|
+
```sh
|
|
102
|
+
cd error-solution-ai-buddy/extension
|
|
103
|
+
npm install
|
|
104
|
+
npm run build
|
|
105
|
+
```
|
|
106
|
+
- Install the extension in VS Code:
|
|
107
|
+
- Use "Install from VSIX..." if you have a packaged file.
|
|
108
|
+
- Or run:
|
|
109
|
+
```sh
|
|
110
|
+
code --install-extension <path-to-extension-folder>
|
|
111
|
+
```
|
|
112
|
+
- Reload VS Code.
|
|
113
|
+
|
|
114
|
+
### 5. Start Using
|
|
115
|
+
- For CLI: Run commands with `errbuddy` prefix.
|
|
116
|
+
- For extension: Use terminal and Error Buddy commands in VS Code.
|
|
117
|
+
### Manual Setup
|
|
118
|
+
|
|
119
|
+
#### Step 1: Install Ollama (Optional - for AI features)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Windows: Download from https://ollama.ai
|
|
123
|
+
|
|
124
|
+
# macOS
|
|
125
|
+
brew install ollama
|
|
126
|
+
|
|
127
|
+
# Linux
|
|
128
|
+
curl -fsSL https://ollama.ai/install.sh | sh
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 2. Start Ollama & Download Model
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
ollama serve # Start the server (keep this running)
|
|
135
|
+
ollama pull llama3.2 # Download the model (~2GB)
|
|
136
|
+
```
|
|
137
|
+
### 3. Install Error Buddy
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# From this directory
|
|
141
|
+
npm install
|
|
142
|
+
npm link # Makes 'errbuddy' available globally
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 4. Use It!
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Instead of: node app.js
|
|
149
|
+
errbuddy node app.js
|
|
150
|
+
|
|
151
|
+
# Instead of: npm start
|
|
152
|
+
errbuddy npm start
|
|
153
|
+
|
|
154
|
+
# Instead of: java MyApp
|
|
155
|
+
errbuddy java MyApp
|
|
156
|
+
|
|
157
|
+
# Instead of: dotnet run
|
|
158
|
+
errbuddy dotnet run
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Supported Languages
|
|
162
|
+
|
|
163
|
+
| Language | Status | Error Types |
|
|
164
|
+
|----------|--------|-------------|
|
|
165
|
+
| JavaScript/Node.js | ✅ Full | TypeError, ReferenceError, SyntaxError, Module errors |
|
|
166
|
+
| Java | ✅ Full | NullPointer, ArrayIndex, ClassNotFound, Compile errors |
|
|
167
|
+
| C#/.NET | ✅ Full | NullReference, Index, CS errors, Runtime exceptions |
|
|
168
|
+
|
|
169
|
+
## CLI Options
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Disable AI (use pattern matching only)
|
|
173
|
+
errbuddy --no-ai node app.js
|
|
174
|
+
|
|
175
|
+
# Use a different Ollama model
|
|
176
|
+
errbuddy --model codellama node app.js
|
|
177
|
+
|
|
178
|
+
# Force offline mode
|
|
179
|
+
errbuddy --offline node app.js
|
|
180
|
+
|
|
181
|
+
# Show examples
|
|
182
|
+
errbuddy examples
|
|
183
|
+
|
|
184
|
+
# Show configuration
|
|
185
|
+
errbuddy config
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## How It Works
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
┌─────────────────────────────────────────┐
|
|
192
|
+
│ You run: errbuddy node app.js │
|
|
193
|
+
└─────────────────────────────────────────┘
|
|
194
|
+
↓
|
|
195
|
+
┌─────────────────────────────────────────┐
|
|
196
|
+
│ CLI spawns: node app.js │
|
|
197
|
+
│ • stdout → displayed normally │
|
|
198
|
+
│ • stderr → captured for analysis │
|
|
199
|
+
└─────────────────────────────────────────┘
|
|
200
|
+
↓
|
|
201
|
+
┌─────────────────────────────────────────┐
|
|
202
|
+
│ Error Detector │
|
|
203
|
+
│ • Detects language (JS/Java/C#) │
|
|
204
|
+
│ • Extracts error type, file, line │
|
|
205
|
+
└─────────────────────────────────────────┘
|
|
206
|
+
↓
|
|
207
|
+
┌─────────────────────────────────────────┐
|
|
208
|
+
│ Ollama AI (local) │
|
|
209
|
+
│ • Receives sanitized error │
|
|
210
|
+
│ • Returns structured explanation │
|
|
211
|
+
└─────────────────────────────────────────┘
|
|
212
|
+
↓
|
|
213
|
+
┌─────────────────────────────────────────┐
|
|
214
|
+
│ Pretty Terminal Output │
|
|
215
|
+
│ • WHAT / WHY / FIX / EXAMPLE │
|
|
216
|
+
└─────────────────────────────────────────┘
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Privacy & Security
|
|
220
|
+
|
|
221
|
+
Your code **never leaves your machine**:
|
|
222
|
+
|
|
223
|
+
- ✅ Ollama runs 100% locally
|
|
224
|
+
- ✅ File paths are stripped before AI processing
|
|
225
|
+
- ✅ No telemetry or analytics
|
|
226
|
+
- ✅ No API keys required
|
|
227
|
+
- ✅ Works completely offline
|
|
228
|
+
|
|
229
|
+
## Project Structure
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
error-solution-ai-buddy/
|
|
233
|
+
├── cli/
|
|
234
|
+
│ ├── index.js # CLI entry point
|
|
235
|
+
│ ├── error-listener.js # Error detection & patterns
|
|
236
|
+
│ └── formatter.js # Terminal output formatting
|
|
237
|
+
├── backend/
|
|
238
|
+
│ └── src/
|
|
239
|
+
│ ├── ai/
|
|
240
|
+
│ │ └── ollama-service.js # Ollama integration
|
|
241
|
+
│ └── services/
|
|
242
|
+
│ └── history-service.js # Error history (SQLite)
|
|
243
|
+
├── docs/
|
|
244
|
+
│ ├── architecture.md # System design
|
|
245
|
+
│ ├── decisions.md # Why we made these choices
|
|
246
|
+
│ └── terminal-integration.md
|
|
247
|
+
├── tests/
|
|
248
|
+
│ └── *.test.js
|
|
249
|
+
├── package.json
|
|
250
|
+
└── README.md
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Configuration
|
|
254
|
+
|
|
255
|
+
Configuration is stored in `~/.errbuddy/config.json`:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"ollamaUrl": "http://localhost:11434",
|
|
260
|
+
"model": "llama3.2",
|
|
261
|
+
"showSpinner": true,
|
|
262
|
+
"saveHistory": true
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Troubleshooting
|
|
267
|
+
|
|
268
|
+
### "Ollama not detected"
|
|
269
|
+
|
|
270
|
+
1. Make sure Ollama is running: `ollama serve`
|
|
271
|
+
2. Check it's accessible: `curl http://localhost:11434/api/tags`
|
|
272
|
+
3. Pull a model: `ollama pull qwen2.5:0.5b`
|
|
273
|
+
|
|
274
|
+
### "AI explanation timed out"
|
|
275
|
+
|
|
276
|
+
- Try a smaller model: `errbuddy --model llama3.2:1b node app.js`
|
|
277
|
+
- Check system resources (Ollama needs ~4GB RAM)
|
|
278
|
+
|
|
279
|
+
### Command not found after `npm link`
|
|
280
|
+
|
|
281
|
+
- On Windows: Restart your terminal
|
|
282
|
+
- On macOS/Linux: Check your PATH includes npm global bin
|
|
283
|
+
|
|
284
|
+
## Contributing
|
|
285
|
+
|
|
286
|
+
1. Fork the repo
|
|
287
|
+
2. Create a feature branch
|
|
288
|
+
3. Submit a PR
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
MIT © 2024
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama AI Service - Handles communication with local Ollama server
|
|
3
|
+
*
|
|
4
|
+
* WHY OLLAMA:
|
|
5
|
+
* 1. 100% free - no API keys needed
|
|
6
|
+
* 2. Runs locally - your code never leaves your machine
|
|
7
|
+
* 3. Works offline - no internet required after model download
|
|
8
|
+
* 4. Fast - local inference with no network latency
|
|
9
|
+
*
|
|
10
|
+
* SETUP:
|
|
11
|
+
* 1. Install Ollama: https://ollama.ai
|
|
12
|
+
* 2. Run: ollama pull llama3.2
|
|
13
|
+
* 3. Run: ollama serve
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* System prompt for error explanation
|
|
18
|
+
*
|
|
19
|
+
* WHY this structure:
|
|
20
|
+
* - Forces consistent output format
|
|
21
|
+
* - Beginner-friendly language
|
|
22
|
+
* - Prevents hallucinations with explicit rules
|
|
23
|
+
*/
|
|
24
|
+
const SYSTEM_PROMPT = `You are an expert programming assistant that explains errors to developers.
|
|
25
|
+
|
|
26
|
+
RULES (VERY IMPORTANT):
|
|
27
|
+
1. Always respond in this EXACT format:
|
|
28
|
+
WHAT: [Name the specific error code/exception (e.g. "NullPointerException", "CS1061") and what it means]
|
|
29
|
+
WHY: [Explain specifically why this code causes that error]
|
|
30
|
+
FIX: [Clear steps to fix the error]
|
|
31
|
+
EXAMPLE: [Short code example if helpful]
|
|
32
|
+
|
|
33
|
+
2. Use simple language a junior developer can understand
|
|
34
|
+
3. Be concise - no long paragraphs
|
|
35
|
+
4. Do NOT assume frameworks (like Spring, React) unless the error explicitly mentions them
|
|
36
|
+
5. Focus on the most likely cause first (typos, missing variables, syntax)
|
|
37
|
+
6. IF suggesting a fix involves installing a new package, ONLY do so if the error is explicitly "Module/Package not found".
|
|
38
|
+
7. If the error mentions "not a statement" and looks like "variable;", explain that standalone variables are not valid statements.
|
|
39
|
+
8. Never make up information - if unsure, say so
|
|
40
|
+
9. Always explicitly mention the error name or code in the "WHAT" section.
|
|
41
|
+
|
|
42
|
+
LANGUAGE-SPECIFIC TIPS:
|
|
43
|
+
- JavaScript: Common issues are undefined/null, async/await, imports
|
|
44
|
+
- Java:
|
|
45
|
+
- "not a statement" often means a standalone variable (e.g. 'x;') which is invalid in Java. It must be an assignment ('x=1;') or method call.
|
|
46
|
+
- Common issues: NullPointer, missing variables, types
|
|
47
|
+
- Avoid suggesting @Autowired unless it's a Spring error
|
|
48
|
+
- C#: Common issues are null reference, missing using, async
|
|
49
|
+
|
|
50
|
+
Remember: Developers are frustrated when they see errors. Be helpful and direct.`;
|
|
51
|
+
|
|
52
|
+
export class AIService {
|
|
53
|
+
constructor(baseUrl = 'http://localhost:11434', model = 'llama3.2') {
|
|
54
|
+
this.baseUrl = baseUrl;
|
|
55
|
+
this.model = model;
|
|
56
|
+
this.timeout = 30000; // 30 second timeout
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if Ollama is running and accessible
|
|
61
|
+
*/
|
|
62
|
+
async checkConnection() {
|
|
63
|
+
try {
|
|
64
|
+
const controller = new AbortController();
|
|
65
|
+
const timeoutId = setTimeout(() => controller.abort(), 3000);
|
|
66
|
+
|
|
67
|
+
const response = await fetch(`${this.baseUrl}/api/tags`, {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
signal: controller.signal, // 3 second timeout for health check
|
|
70
|
+
}).finally(() => clearTimeout(timeoutId));
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
|
|
78
|
+
// Check if the model we want is available
|
|
79
|
+
const models = data.models || [];
|
|
80
|
+
const modelBaseName = this.model.split(':')[0];
|
|
81
|
+
const hasModel = models.some(m => m.name.startsWith(modelBaseName));
|
|
82
|
+
|
|
83
|
+
if (!hasModel && models.length > 0) {
|
|
84
|
+
// Use first available model as fallback
|
|
85
|
+
this.model = models[0].name;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return true;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get explanation for an error from Ollama
|
|
96
|
+
*/
|
|
97
|
+
async explainError(errorText, language = 'unknown') {
|
|
98
|
+
const prompt = this.buildPrompt(errorText, language);
|
|
99
|
+
|
|
100
|
+
const controller = new AbortController();
|
|
101
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const response = await fetch(`${this.baseUrl}/api/generate`, {
|
|
105
|
+
method: 'POST',
|
|
106
|
+
headers: {
|
|
107
|
+
'Content-Type': 'application/json',
|
|
108
|
+
},
|
|
109
|
+
body: JSON.stringify({
|
|
110
|
+
model: this.model,
|
|
111
|
+
prompt: prompt,
|
|
112
|
+
system: SYSTEM_PROMPT,
|
|
113
|
+
stream: false,
|
|
114
|
+
options: {
|
|
115
|
+
temperature: 0.1, // Very low to prevent hallucinations
|
|
116
|
+
top_p: 0.9,
|
|
117
|
+
num_predict: 500, // Limit response length
|
|
118
|
+
}
|
|
119
|
+
}),
|
|
120
|
+
signal: controller.signal,
|
|
121
|
+
}).finally(() => clearTimeout(timeoutId));
|
|
122
|
+
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
let errorMsg = '';
|
|
125
|
+
try {
|
|
126
|
+
const errorJson = await response.json();
|
|
127
|
+
errorMsg = errorJson.error || JSON.stringify(errorJson);
|
|
128
|
+
} catch {
|
|
129
|
+
errorMsg = await response.text();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check for memory error
|
|
133
|
+
if (errorMsg.includes('memory')) {
|
|
134
|
+
throw new Error('Not enough RAM. Try: errbuddy --model qwen2.5:0.5b');
|
|
135
|
+
}
|
|
136
|
+
throw new Error(`Ollama returned ${response.status}: ${errorMsg}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const data = await response.json();
|
|
140
|
+
|
|
141
|
+
// Check for error in response
|
|
142
|
+
if (data.error) {
|
|
143
|
+
throw new Error(data.error);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return this.parseResponse(data.response);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
if (error.name === 'TimeoutError' || error.name === 'AbortError') {
|
|
149
|
+
throw new Error('AI explanation timed out. Try a smaller model.');
|
|
150
|
+
}
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Build the prompt for the AI
|
|
157
|
+
*/
|
|
158
|
+
buildPrompt(errorText, language) {
|
|
159
|
+
const langName = {
|
|
160
|
+
javascript: 'JavaScript/Node.js',
|
|
161
|
+
java: 'Java',
|
|
162
|
+
csharp: 'C#/.NET',
|
|
163
|
+
unknown: 'programming'
|
|
164
|
+
}[language] || language;
|
|
165
|
+
|
|
166
|
+
return `Explain this ${langName} error to a developer:
|
|
167
|
+
|
|
168
|
+
\`\`\`
|
|
169
|
+
${errorText}
|
|
170
|
+
\`\`\`
|
|
171
|
+
|
|
172
|
+
Remember to use the format: WHAT, WHY, FIX, EXAMPLE`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Parse the AI response into structured format
|
|
177
|
+
*/
|
|
178
|
+
parseResponse(response) {
|
|
179
|
+
const result = {
|
|
180
|
+
what: null,
|
|
181
|
+
why: null,
|
|
182
|
+
fix: null,
|
|
183
|
+
example: null,
|
|
184
|
+
raw: response
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// Try to extract structured parts
|
|
188
|
+
const whatMatch = response.match(/WHAT:\s*(.+?)(?=WHY:|FIX:|EXAMPLE:|$)/is);
|
|
189
|
+
const whyMatch = response.match(/WHY:\s*(.+?)(?=WHAT:|FIX:|EXAMPLE:|$)/is);
|
|
190
|
+
const fixMatch = response.match(/FIX:\s*(.+?)(?=WHAT:|WHY:|EXAMPLE:|$)/is);
|
|
191
|
+
const exampleMatch = response.match(/EXAMPLE:\s*(.+?)(?=WHAT:|WHY:|FIX:|$)/is);
|
|
192
|
+
|
|
193
|
+
if (whatMatch) result.what = whatMatch[1].trim();
|
|
194
|
+
if (whyMatch) result.why = whyMatch[1].trim();
|
|
195
|
+
if (fixMatch) result.fix = fixMatch[1].trim();
|
|
196
|
+
if (exampleMatch) result.example = exampleMatch[1].trim();
|
|
197
|
+
|
|
198
|
+
// If structured parsing failed, try to make sense of the response
|
|
199
|
+
if (!result.what && !result.why && !result.fix) {
|
|
200
|
+
// Split by sentences and assign
|
|
201
|
+
const sentences = response.split(/[.!]\s+/).filter(s => s.trim());
|
|
202
|
+
if (sentences.length >= 1) result.what = sentences[0].trim() + '.';
|
|
203
|
+
if (sentences.length >= 2) result.why = sentences[1].trim() + '.';
|
|
204
|
+
if (sentences.length >= 3) result.fix = sentences.slice(2).join('. ').trim();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Extract code blocks for example
|
|
208
|
+
if (!result.example) {
|
|
209
|
+
const codeMatch = response.match(/```[\w]*\n?([\s\S]+?)```/);
|
|
210
|
+
if (codeMatch) {
|
|
211
|
+
result.example = codeMatch[1].trim();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Stream explanation (for future use - better UX for long responses)
|
|
220
|
+
* Currently not used but ready for implementation
|
|
221
|
+
*/
|
|
222
|
+
async *streamExplanation(errorText, language = 'unknown') {
|
|
223
|
+
const prompt = this.buildPrompt(errorText, language);
|
|
224
|
+
|
|
225
|
+
const response = await fetch(`${this.baseUrl}/api/generate`, {
|
|
226
|
+
method: 'POST',
|
|
227
|
+
headers: {
|
|
228
|
+
'Content-Type': 'application/json',
|
|
229
|
+
},
|
|
230
|
+
body: JSON.stringify({
|
|
231
|
+
model: this.model,
|
|
232
|
+
prompt: prompt,
|
|
233
|
+
system: SYSTEM_PROMPT,
|
|
234
|
+
stream: true,
|
|
235
|
+
options: {
|
|
236
|
+
temperature: 0.3,
|
|
237
|
+
num_predict: 500,
|
|
238
|
+
}
|
|
239
|
+
}),
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const reader = response.body.getReader();
|
|
243
|
+
const decoder = new TextDecoder();
|
|
244
|
+
|
|
245
|
+
while (true) {
|
|
246
|
+
const { done, value } = await reader.read();
|
|
247
|
+
if (done) break;
|
|
248
|
+
|
|
249
|
+
const chunk = decoder.decode(value);
|
|
250
|
+
const lines = chunk.split('\n').filter(line => line.trim());
|
|
251
|
+
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
try {
|
|
254
|
+
const data = JSON.parse(line);
|
|
255
|
+
if (data.response) {
|
|
256
|
+
yield data.response;
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
// Ignore JSON parse errors for incomplete chunks
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|