wolverine-ai 3.9.0 → 3.9.1
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/package.json +1 -1
- package/src/agent/agent-engine.js +4 -0
- package/src/core/ai-client.js +18 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wolverine-ai",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.1",
|
|
4
4
|
"description": "Self-healing Node.js server framework powered by AI. Catches crashes, diagnoses errors, generates fixes, verifies, and restarts — automatically.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -446,6 +446,10 @@ class AgentEngine {
|
|
|
446
446
|
return { success: false, summary: "Token budget exhausted", filesModified: this.filesModified, turnCount: this.turnCount, totalTokens: this.totalTokens };
|
|
447
447
|
}
|
|
448
448
|
|
|
449
|
+
if (!response.choices || !response.choices[0]) {
|
|
450
|
+
console.log(chalk.red(` ⚠️ AI returned no choices: ${JSON.stringify(response).slice(0, 200)}`));
|
|
451
|
+
return { success: false, summary: "AI returned empty response", filesModified: this.filesModified, turnCount: this.turnCount, totalTokens: this.totalTokens };
|
|
452
|
+
}
|
|
449
453
|
const choice = response.choices[0];
|
|
450
454
|
const assistantMessage = choice.message || choice;
|
|
451
455
|
this.messages.push(assistantMessage);
|
package/src/core/ai-client.js
CHANGED
|
@@ -615,13 +615,27 @@ ${backupSourceCode ? `## Last Known Working Version\n\`\`\`javascript\n${backupS
|
|
|
615
615
|
Include both if needed, or just one.`;
|
|
616
616
|
|
|
617
617
|
const result = await aiCall({ model, systemPrompt, userPrompt, maxTokens: 2048, category: "coding" });
|
|
618
|
-
const content = result.content;
|
|
619
|
-
|
|
618
|
+
const content = (result.content || "").trim();
|
|
619
|
+
|
|
620
|
+
// Strip thinking tags (Gemma), markdown fences, and any prefix text
|
|
621
|
+
let cleaned = content
|
|
622
|
+
.replace(/<\|channel>.*?<channel\|>/gs, "")
|
|
623
|
+
.replace(/<\|think\|>[\s\S]*?<\|\/think\|>/g, "")
|
|
624
|
+
.replace(/^```(?:json)?\s*/gm, "")
|
|
625
|
+
.replace(/```\s*$/gm, "")
|
|
626
|
+
.trim();
|
|
627
|
+
|
|
628
|
+
// Extract JSON object from response
|
|
629
|
+
const jsonMatch = cleaned.match(/\{[\s\S]*"(?:explanation|changes|commands)"[\s\S]*\}/);
|
|
630
|
+
if (jsonMatch) cleaned = jsonMatch[0];
|
|
620
631
|
|
|
621
632
|
try {
|
|
622
633
|
return JSON.parse(cleaned);
|
|
623
|
-
} catch
|
|
624
|
-
|
|
634
|
+
} catch {
|
|
635
|
+
// Last resort: try to find any JSON object
|
|
636
|
+
const anyJson = cleaned.match(/\{[\s\S]*\}/);
|
|
637
|
+
if (anyJson) try { return JSON.parse(anyJson[0]); } catch {}
|
|
638
|
+
throw new Error(`AI response was not valid JSON`);
|
|
625
639
|
}
|
|
626
640
|
}
|
|
627
641
|
|