mycontext-cli 4.1.4 → 4.2.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/README.md +231 -12
- package/dist/README.md +231 -12
- package/dist/agents/implementations/ArchitectAgent.d.ts.map +1 -1
- package/dist/agents/implementations/ArchitectAgent.js +9 -1
- package/dist/agents/implementations/ArchitectAgent.js.map +1 -1
- package/dist/agents/implementations/BackendDevAgent.d.ts +1 -1
- package/dist/agents/implementations/BackendDevAgent.d.ts.map +1 -1
- package/dist/agents/implementations/BackendDevAgent.js +29 -16
- package/dist/agents/implementations/BackendDevAgent.js.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.d.ts.map +1 -1
- package/dist/agents/implementations/CodeGenSubAgent.js +17 -9
- package/dist/agents/implementations/CodeGenSubAgent.js.map +1 -1
- package/dist/agents/implementations/EnhancementAgent.js.map +1 -1
- package/dist/agents/implementations/FeatureAssemblyAgent.d.ts +1 -1
- package/dist/agents/implementations/FeatureAssemblyAgent.d.ts.map +1 -1
- package/dist/agents/implementations/FeatureAssemblyAgent.js +10 -9
- package/dist/agents/implementations/FeatureAssemblyAgent.js.map +1 -1
- package/dist/agents/implementations/PromptConstructorAgent.d.ts.map +1 -1
- package/dist/agents/implementations/PromptConstructorAgent.js +26 -42
- package/dist/agents/implementations/PromptConstructorAgent.js.map +1 -1
- package/dist/clients/ProviderChain.d.ts +6 -65
- package/dist/clients/ProviderChain.d.ts.map +1 -1
- package/dist/clients/ProviderChain.js +34 -194
- package/dist/clients/ProviderChain.js.map +1 -1
- package/dist/commands/agent.js +1 -1
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/assemble-features.js +1 -1
- package/dist/commands/assemble-features.js.map +1 -1
- package/dist/commands/design-analyze.js +2 -2
- package/dist/commands/generate-context-files.d.ts.map +1 -1
- package/dist/commands/generate-context-files.js +13 -0
- package/dist/commands/generate-context-files.js.map +1 -1
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +96 -23
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/sync-readme.js +1 -1
- package/dist/commands/sync-readme.js.map +1 -1
- package/dist/core/agents/DependencySentinel.d.ts +15 -0
- package/dist/core/agents/DependencySentinel.d.ts.map +1 -0
- package/dist/core/agents/DependencySentinel.js +141 -0
- package/dist/core/agents/DependencySentinel.js.map +1 -0
- package/dist/core/ai/AICore.d.ts +48 -0
- package/dist/core/ai/AICore.d.ts.map +1 -0
- package/dist/core/ai/AICore.js +228 -0
- package/dist/core/ai/AICore.js.map +1 -0
- package/dist/core/brain/BrainClient.d.ts +16 -0
- package/dist/core/brain/BrainClient.d.ts.map +1 -0
- package/dist/core/brain/BrainClient.js +151 -0
- package/dist/core/brain/BrainClient.js.map +1 -0
- package/dist/package.json +6 -5
- package/dist/types/living-context.d.ts +76 -0
- package/dist/types/living-context.d.ts.map +1 -0
- package/dist/types/living-context.js +3 -0
- package/dist/types/living-context.js.map +1 -0
- package/dist/utils/FileGenerator.d.ts +9 -0
- package/dist/utils/FileGenerator.d.ts.map +1 -0
- package/dist/utils/FileGenerator.js +106 -0
- package/dist/utils/FileGenerator.js.map +1 -0
- package/dist/utils/NextJSProjectGenerator.d.ts.map +1 -1
- package/dist/utils/NextJSProjectGenerator.js +59 -0
- package/dist/utils/NextJSProjectGenerator.js.map +1 -1
- package/dist/utils/contextRenderer.d.ts +12 -0
- package/dist/utils/contextRenderer.d.ts.map +1 -0
- package/dist/utils/contextRenderer.js +105 -0
- package/dist/utils/contextRenderer.js.map +1 -0
- package/dist/utils/fileSystem.d.ts +4 -0
- package/dist/utils/fileSystem.d.ts.map +1 -1
- package/dist/utils/fileSystem.js +19 -0
- package/dist/utils/fileSystem.js.map +1 -1
- package/dist/utils/hybridAIClient.d.ts +12 -117
- package/dist/utils/hybridAIClient.d.ts.map +1 -1
- package/dist/utils/hybridAIClient.js +31 -750
- package/dist/utils/hybridAIClient.js.map +1 -1
- package/package.json +6 -5
|
@@ -1,591 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
3
|
exports.HybridAIClient = void 0;
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const fs = __importStar(require("fs"));
|
|
48
|
-
const path = __importStar(require("path"));
|
|
49
|
-
// Load environment variables from project files
|
|
50
|
-
function loadEnvironmentVariables() {
|
|
51
|
-
try {
|
|
52
|
-
const dotenv = require("dotenv");
|
|
53
|
-
const dotenvExpand = require("dotenv-expand");
|
|
54
|
-
const cwd = process.cwd();
|
|
55
|
-
const candidates = [
|
|
56
|
-
path.join(cwd, ".mycontext", ".env.local"),
|
|
57
|
-
path.join(cwd, ".mycontext", ".env"),
|
|
58
|
-
path.join(cwd, ".env.local"),
|
|
59
|
-
path.join(cwd, ".env"),
|
|
60
|
-
];
|
|
61
|
-
for (const p of candidates) {
|
|
62
|
-
if (fs.existsSync(p)) {
|
|
63
|
-
const result = dotenv.config({ path: p, override: true });
|
|
64
|
-
dotenvExpand.expand(result);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
// Ignore errors
|
|
70
|
-
}
|
|
71
|
-
}
|
|
4
|
+
const AICore_1 = require("../core/ai/AICore");
|
|
5
|
+
/**
|
|
6
|
+
* HybridAIClient (Legacy Wrapper)
|
|
7
|
+
*
|
|
8
|
+
* This class is now a backward-compatibility layer that delegates to AICore.
|
|
9
|
+
* New code should use AICore.getInstance().getBestClient() directly.
|
|
10
|
+
*/
|
|
72
11
|
class HybridAIClient {
|
|
73
12
|
constructor() {
|
|
74
|
-
|
|
75
|
-
this.currentProvider = null;
|
|
76
|
-
this.config = null;
|
|
77
|
-
// Load environment variables first
|
|
78
|
-
loadEnvironmentVariables();
|
|
79
|
-
this.loadConfig();
|
|
80
|
-
this.initializeProviders();
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Load AI provider configuration
|
|
84
|
-
*/
|
|
85
|
-
loadConfig() {
|
|
13
|
+
// AICore is likely already initialized by the command entry point
|
|
86
14
|
try {
|
|
87
|
-
|
|
88
|
-
const configData = fs.readFileSync(configPath, "utf8");
|
|
89
|
-
this.config = JSON.parse(configData);
|
|
90
|
-
}
|
|
91
|
-
catch (error) {
|
|
92
|
-
logger_1.logger.debug("Could not load config, using defaults");
|
|
93
|
-
this.config = null;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Initialize available AI providers based on configuration
|
|
98
|
-
*/
|
|
99
|
-
async initializeProviders() {
|
|
100
|
-
// Add user API key providers first (highest priority)
|
|
101
|
-
// Claude Agent SDK (highest priority for advanced features)
|
|
102
|
-
// Always try ClaudeAgentClient if it has an API key (simplified approach)
|
|
103
|
-
const claudeAgentClient = new claudeAgentClient_1.ClaudeAgentClient();
|
|
104
|
-
if (claudeAgentClient.hasApiKey()) {
|
|
105
|
-
// Determine provider name based on mode
|
|
106
|
-
const providerName = claudeAgentClient.isGrokModeEnabled
|
|
107
|
-
? "xai"
|
|
108
|
-
: "claude-agent";
|
|
109
|
-
// Log the provider being used (only once)
|
|
110
|
-
if (!HybridAIClient.hasLoggedInitialization) {
|
|
111
|
-
if (claudeAgentClient.isGrokModeEnabled) {
|
|
112
|
-
console.log(chalk_1.default.blue("🤖 Using Grok 4 via X AI API (direct)"));
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
console.log(chalk_1.default.blue("🎯 Using Claude Agent SDK (supports Claude, Bedrock, Vertex AI)"));
|
|
116
|
-
}
|
|
117
|
-
HybridAIClient.hasLoggedInitialization = true;
|
|
118
|
-
}
|
|
119
|
-
this.providers.push({
|
|
120
|
-
name: providerName,
|
|
121
|
-
priority: 0, // Highest priority for Agent SDK
|
|
122
|
-
client: claudeAgentClient,
|
|
123
|
-
isAvailable: () => claudeAgentClient.checkConnection(),
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
// GitHub Models (High-quality GPT models)
|
|
127
|
-
const githubClient = new githubModelsClient_1.GitHubModelsClient();
|
|
128
|
-
if (githubClient.hasApiKey()) {
|
|
129
|
-
if (process.env.DEBUG || process.env.VERBOSE) {
|
|
130
|
-
console.log(chalk_1.default.gray(`[HybridAIClient] Registering GitHub Models provider`));
|
|
131
|
-
}
|
|
132
|
-
this.providers.push({
|
|
133
|
-
name: "github",
|
|
134
|
-
priority: 0.5, // Between Claude (0) and OpenRouter (1)
|
|
135
|
-
client: githubClient,
|
|
136
|
-
isAvailable: () => githubClient.testConnection(),
|
|
137
|
-
});
|
|
138
|
-
// Log if this is the only provider (or first high-priority)
|
|
139
|
-
if (!HybridAIClient.hasLoggedInitialization) {
|
|
140
|
-
console.log(chalk_1.default.blue("🧠 Using GitHub Models (GPT-4o) - High Quality"));
|
|
141
|
-
HybridAIClient.hasLoggedInitialization = true;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// OpenRouter (recommended free tier option - prioritized over XAI)
|
|
145
|
-
const openRouterClient = new openRouterClient_1.OpenRouterClient();
|
|
146
|
-
if (openRouterClient.hasApiKey()) {
|
|
147
|
-
if (process.env.DEBUG || process.env.VERBOSE) {
|
|
148
|
-
console.log(chalk_1.default.gray(`[HybridAIClient] Registering OpenRouter provider`));
|
|
149
|
-
}
|
|
150
|
-
this.providers.push({
|
|
151
|
-
name: "openrouter",
|
|
152
|
-
priority: 1, // After Claude, before Gemini/XAI
|
|
153
|
-
client: openRouterClient,
|
|
154
|
-
isAvailable: () => openRouterClient.checkConnection(),
|
|
155
|
-
});
|
|
156
|
-
// Log if this is the only provider
|
|
157
|
-
if (!HybridAIClient.hasLoggedInitialization &&
|
|
158
|
-
this.providers.length === 1) {
|
|
159
|
-
console.log(chalk_1.default.blue("🧠 Using OpenRouter (DeepSeek R1) - Free Tier"));
|
|
160
|
-
HybridAIClient.hasLoggedInitialization = true;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else if (process.env.DEBUG || process.env.VERBOSE) {
|
|
164
|
-
console.log(chalk_1.default.yellow(`[HybridAIClient] OpenRouter skipped: No API key found`));
|
|
165
|
-
}
|
|
166
|
-
// Gemini (multimodal support, visual generation)
|
|
167
|
-
const geminiClient = new geminiClient_1.GeminiClient();
|
|
168
|
-
if (geminiClient.hasApiKey()) {
|
|
169
|
-
this.providers.push({
|
|
170
|
-
name: "gemini",
|
|
171
|
-
priority: 2, // After Claude/OpenRouter, before XAI
|
|
172
|
-
client: geminiClient,
|
|
173
|
-
isAvailable: async () => await geminiClient.testConnection(),
|
|
174
|
-
});
|
|
175
|
-
// Log if this is the only provider
|
|
176
|
-
if (!HybridAIClient.hasLoggedInitialization &&
|
|
177
|
-
this.providers.length === 1) {
|
|
178
|
-
console.log(chalk_1.default.blue("✨ Using Gemini 2.0 Flash (Multimodal + Visual Generation)"));
|
|
179
|
-
HybridAIClient.hasLoggedInitialization = true;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
// XAI/Grok (fast reasoning, multimodal support)
|
|
183
|
-
const xaiClient = new XAIClient_1.XAIClient();
|
|
184
|
-
if (xaiClient.hasApiKey()) {
|
|
185
|
-
this.providers.push({
|
|
186
|
-
name: "xai",
|
|
187
|
-
priority: 3, // After Claude/OpenRouter/Gemini
|
|
188
|
-
client: xaiClient,
|
|
189
|
-
isAvailable: async () => await xaiClient.checkConnection(),
|
|
190
|
-
});
|
|
191
|
-
// Log if this is the only provider
|
|
192
|
-
if (!HybridAIClient.hasLoggedInitialization &&
|
|
193
|
-
this.providers.length === 1) {
|
|
194
|
-
console.log(chalk_1.default.blue("✨ Using XAI Grok (Fast Reasoning)"));
|
|
195
|
-
HybridAIClient.hasLoggedInitialization = true;
|
|
196
|
-
}
|
|
15
|
+
AICore_1.AICore.getInstance();
|
|
197
16
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
this.providers.forEach((p) => {
|
|
203
|
-
logger_1.logger.verbose(` • ${p.name} (priority: ${p.priority})`);
|
|
17
|
+
catch (e) {
|
|
18
|
+
AICore_1.AICore.getInstance({
|
|
19
|
+
workingDirectory: process.cwd(),
|
|
20
|
+
fallbackEnabled: true
|
|
204
21
|
});
|
|
205
22
|
}
|
|
206
23
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
*/
|
|
210
|
-
async getBestProvider(excludeProviders = new Set()) {
|
|
211
|
-
// Optional override via env - this takes highest priority
|
|
212
|
-
const preferredName = process.env.MYCONTEXT_PROVIDER || process.env.AI_PROVIDER || "";
|
|
213
|
-
if (process.env.DEBUG || process.env.VERBOSE) {
|
|
214
|
-
console.log(`[HybridAIClient] getBestProvider check: MYCONTEXT_PROVIDER=${!!process.env.MYCONTEXT_PROVIDER}, AI_PROVIDER=${!!process.env.AI_PROVIDER}`);
|
|
215
|
-
}
|
|
216
|
-
if (preferredName) {
|
|
217
|
-
const preferred = this.providers.find((p) => p.name === preferredName);
|
|
218
|
-
if (preferred) {
|
|
219
|
-
console.log(`[HybridAIClient] Environment override: using ${preferredName}`);
|
|
220
|
-
try {
|
|
221
|
-
if (await preferred.isAvailable()) {
|
|
222
|
-
this.currentProvider = preferred;
|
|
223
|
-
return preferred;
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
console.log(`[HybridAIClient] Preferred provider ${preferred.name} not available, falling back to priority order`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
console.log(`[HybridAIClient] Preferred provider ${preferred.name} not available: ${error}, falling back to priority order`);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
console.log(`[HybridAIClient] Preferred provider ${preferredName} not found in available providers`);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
// Choose the highest-priority available provider (excluding already-attempted ones)
|
|
238
|
-
for (const provider of this.providers) {
|
|
239
|
-
// Skip if this provider was already attempted
|
|
240
|
-
if (excludeProviders.has(provider.name)) {
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
try {
|
|
244
|
-
const isAvailable = await provider.isAvailable();
|
|
245
|
-
if (isAvailable) {
|
|
246
|
-
this.currentProvider = provider;
|
|
247
|
-
return provider;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
console.log(`[HybridAIClient] Provider ${provider.name} not available: ${error}`);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
return null;
|
|
24
|
+
get client() {
|
|
25
|
+
return AICore_1.AICore.getInstance().getBestClient();
|
|
255
26
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Expose current/next-best provider name for UX (e.g., spinner labels)
|
|
258
|
-
*/
|
|
259
27
|
async getActiveProviderName() {
|
|
260
|
-
const
|
|
261
|
-
return
|
|
28
|
+
const client = this.client;
|
|
29
|
+
return client.providerName || "hybrid";
|
|
262
30
|
}
|
|
263
|
-
/**
|
|
264
|
-
* Best-effort model name for generic text generation per provider
|
|
265
|
-
*/
|
|
266
31
|
async getActiveTextModelName() {
|
|
267
|
-
|
|
268
|
-
if (!provider)
|
|
269
|
-
return "unknown";
|
|
270
|
-
if (provider.name === "github") {
|
|
271
|
-
// If user provided candidates via env, prefer the first
|
|
272
|
-
const envCandidates = process.env.MYCONTEXT_MODEL_CANDIDATES;
|
|
273
|
-
if (envCandidates) {
|
|
274
|
-
const first = envCandidates
|
|
275
|
-
.split(",")
|
|
276
|
-
.map((s) => s.trim())
|
|
277
|
-
.filter(Boolean)[0];
|
|
278
|
-
if (first)
|
|
279
|
-
return first;
|
|
280
|
-
}
|
|
281
|
-
return (this.config?.github?.models?.["component-generator"]?.name ||
|
|
282
|
-
process.env.MYCONTEXT_MODEL ||
|
|
283
|
-
"grok-3");
|
|
284
|
-
}
|
|
285
|
-
if (provider.name === "openai") {
|
|
286
|
-
return (this.config?.openai?.models?.["text-generator"]?.name || "gpt-3.5-turbo");
|
|
287
|
-
}
|
|
288
|
-
if (provider.name === "claude") {
|
|
289
|
-
return (this.config?.claude?.models?.["text-generator"]?.name ||
|
|
290
|
-
"claude-3-5-sonnet-20241022");
|
|
291
|
-
}
|
|
292
|
-
if (provider.name === "huggingface") {
|
|
293
|
-
return (this.config?.huggingface?.models?.["component-generator"]?.name ||
|
|
294
|
-
"mycontext/react-component-generator");
|
|
295
|
-
}
|
|
296
|
-
if (provider.name === "gemini") {
|
|
297
|
-
return (this.config?.gemini?.models?.["text-generator"]?.name ||
|
|
298
|
-
"gemini-2.0-flash");
|
|
299
|
-
}
|
|
300
|
-
if (provider.name === "xai") {
|
|
301
|
-
return (this.config?.xai?.models?.["text-generator"]?.name ||
|
|
302
|
-
"grok-4-fast-reasoning");
|
|
303
|
-
}
|
|
304
|
-
if (provider.name === "openrouter") {
|
|
305
|
-
return "deepseek-ai/DeepSeek-R1";
|
|
306
|
-
}
|
|
307
|
-
// Default model name
|
|
308
|
-
return "qwen3-coder";
|
|
32
|
+
return "unified-model";
|
|
309
33
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
async generateComponentRefinement(componentCode, prompt, options = {}) {
|
|
314
|
-
const provider = await this.getBestProvider();
|
|
315
|
-
if (!provider) {
|
|
316
|
-
throw new Error("No AI providers available. Please configure Qwen API key or other providers.");
|
|
317
|
-
}
|
|
318
|
-
try {
|
|
319
|
-
logger_1.logger.verbose(`Using AI provider: ${provider.name}`);
|
|
320
|
-
let result;
|
|
321
|
-
if (provider.name === "qwen") {
|
|
322
|
-
const qwenClient = provider.client;
|
|
323
|
-
result = await qwenClient.generateComponentRefinement(componentCode, prompt, options);
|
|
324
|
-
}
|
|
325
|
-
else if (provider.name === "github") {
|
|
326
|
-
const githubClient = provider.client;
|
|
327
|
-
result = await githubClient.generateComponentRefinement(componentCode, prompt, options);
|
|
328
|
-
}
|
|
329
|
-
else if (provider.name === "openai") {
|
|
330
|
-
const openaiClient = provider.client;
|
|
331
|
-
result = await openaiClient.generateComponentRefinement(componentCode, prompt, options);
|
|
332
|
-
}
|
|
333
|
-
else if (provider.name === "claude") {
|
|
334
|
-
const claudeClient = provider.client;
|
|
335
|
-
result = await claudeClient.generateComponentRefinement(componentCode, prompt, options);
|
|
336
|
-
}
|
|
337
|
-
else if (provider.name === "huggingface") {
|
|
338
|
-
const huggingFaceClient = provider.client;
|
|
339
|
-
result = await huggingFaceClient.generateComponentRefinement(componentCode, prompt, options);
|
|
340
|
-
}
|
|
341
|
-
else if (provider.name === "gemini") {
|
|
342
|
-
const geminiClient = provider.client;
|
|
343
|
-
const response = await geminiClient.generateText(`Refine this React component: ${componentCode}\n\nUser request: ${prompt}`, options);
|
|
344
|
-
result = response.text;
|
|
345
|
-
}
|
|
346
|
-
else if (provider.name === "xai") {
|
|
347
|
-
const xaiClient = provider.client;
|
|
348
|
-
const modelName = await this.getActiveTextModelName();
|
|
349
|
-
result = await xaiClient.generateComponentRefinement(componentCode, prompt, { ...options, model: modelName });
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
// No fallback - fail cleanly
|
|
353
|
-
throw new Error("AI generation failed - no fallbacks allowed");
|
|
354
|
-
}
|
|
355
|
-
// Extract code and explanation
|
|
356
|
-
const { code, explanation } = this.parseAIResponse(result);
|
|
357
|
-
return {
|
|
358
|
-
code,
|
|
359
|
-
provider: provider.name,
|
|
360
|
-
explanation,
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
catch (error) {
|
|
364
|
-
console.log(`[HybridAIClient] Provider ${provider.name} failed: ${error.message}`);
|
|
365
|
-
// Try next provider
|
|
366
|
-
const nextProvider = this.providers.find((p) => p.priority > provider.priority);
|
|
367
|
-
if (nextProvider) {
|
|
368
|
-
console.log(`[HybridAIClient] Trying next provider: ${nextProvider.name}`);
|
|
369
|
-
return this.generateComponentRefinement(componentCode, prompt, options);
|
|
370
|
-
}
|
|
371
|
-
throw error;
|
|
372
|
-
}
|
|
34
|
+
async generateText(prompt, options = {}) {
|
|
35
|
+
const text = await this.client.generateText(prompt, options);
|
|
36
|
+
return { text, provider: await this.getActiveProviderName() };
|
|
373
37
|
}
|
|
374
|
-
/**
|
|
375
|
-
* Generate new component using the best available provider
|
|
376
|
-
*/
|
|
377
38
|
async generateComponent(prompt, options = {}) {
|
|
378
|
-
|
|
39
|
+
const result = await this.client.generateComponent(prompt, undefined, options);
|
|
40
|
+
const { code, explanation } = this.parseAIResponse(result);
|
|
41
|
+
return { code, provider: await this.getActiveProviderName(), explanation };
|
|
379
42
|
}
|
|
380
|
-
async
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
continue;
|
|
385
|
-
}
|
|
386
|
-
try {
|
|
387
|
-
logger_1.logger.verbose(`Using AI provider: ${provider.name}`);
|
|
388
|
-
let result;
|
|
389
|
-
if (provider.name === "qwen") {
|
|
390
|
-
const qwenClient = provider.client;
|
|
391
|
-
result = await qwenClient.generateComponent(prompt, options);
|
|
392
|
-
}
|
|
393
|
-
else if (provider.name === "github") {
|
|
394
|
-
const githubClient = provider.client;
|
|
395
|
-
result = await githubClient.generateComponent(prompt, options);
|
|
396
|
-
}
|
|
397
|
-
else if (provider.name === "openai") {
|
|
398
|
-
const openaiClient = provider.client;
|
|
399
|
-
result = await openaiClient.generateComponent(prompt, options);
|
|
400
|
-
}
|
|
401
|
-
else if (provider.name === "claude") {
|
|
402
|
-
const claudeClient = provider.client;
|
|
403
|
-
result = await claudeClient.generateComponent(prompt, options);
|
|
404
|
-
}
|
|
405
|
-
else if (provider.name === "huggingface") {
|
|
406
|
-
const huggingFaceClient = provider.client;
|
|
407
|
-
result = await huggingFaceClient.generateComponent(prompt, options);
|
|
408
|
-
}
|
|
409
|
-
else if (provider.name === "gemini") {
|
|
410
|
-
const geminiClient = provider.client;
|
|
411
|
-
const response = await geminiClient.generateComponent(prompt, options);
|
|
412
|
-
result = response.code;
|
|
413
|
-
}
|
|
414
|
-
else if (provider.name === "xai") {
|
|
415
|
-
const xaiClient = provider.client;
|
|
416
|
-
const modelName = await this.getActiveTextModelName();
|
|
417
|
-
result = await xaiClient.generateComponent(prompt, {
|
|
418
|
-
...options,
|
|
419
|
-
model: modelName,
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
else if (provider.name === "hosted") {
|
|
423
|
-
const hostedClient = provider.client;
|
|
424
|
-
const response = await hostedClient.generateComponent(prompt, options);
|
|
425
|
-
if (response.success && response.content) {
|
|
426
|
-
result = response.content;
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
throw new Error(response.error || "Hosted API generation failed");
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
// No fallback - fail cleanly
|
|
434
|
-
throw new Error("AI generation failed - no fallbacks allowed");
|
|
435
|
-
}
|
|
436
|
-
// Extract code and explanation
|
|
437
|
-
const { code, explanation } = this.parseAIResponse(result);
|
|
438
|
-
return {
|
|
439
|
-
code,
|
|
440
|
-
provider: provider.name,
|
|
441
|
-
explanation,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
catch (error) {
|
|
445
|
-
console.log(`[HybridAIClient] Provider ${provider.name} failed: ${error.message}`);
|
|
446
|
-
// Add to failed list and continue to next provider
|
|
447
|
-
failedProviders.push(provider.name);
|
|
448
|
-
// If this is a 402 Payment Required error, don't retry the same provider
|
|
449
|
-
if (error.message.includes("402") ||
|
|
450
|
-
error.message.includes("Payment Required")) {
|
|
451
|
-
console.log(`[HybridAIClient] Skipping ${provider.name} due to payment/credit issues`);
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
// If this is a rate limit error, add to failed list but don't give up immediately
|
|
455
|
-
if (error.message.includes("429") ||
|
|
456
|
-
error.message.includes("Rate limit") ||
|
|
457
|
-
error.message.includes("RateLimitReached")) {
|
|
458
|
-
console.log(`[HybridAIClient] ${provider.name} rate limited, will try other providers first`);
|
|
459
|
-
// Don't add to failed list immediately - try other providers first
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
// All providers failed
|
|
465
|
-
const failedList = failedProviders.join(", ");
|
|
466
|
-
console.log(chalk_1.default.red("❌ All AI providers failed"));
|
|
467
|
-
console.log(chalk_1.default.yellow("💡 All AI providers failed. Retry options:"));
|
|
468
|
-
console.log(chalk_1.default.gray(" 1. Wait for rate limits to reset"));
|
|
469
|
-
console.log(chalk_1.default.gray(" 2. Check API key configuration"));
|
|
470
|
-
console.log(chalk_1.default.gray(" 3. Try again later"));
|
|
471
|
-
throw new Error(`All AI providers failed: ${failedList}. Retry when conditions improve.`);
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Generate generic text (used for PRD, types, brand, etc.)
|
|
475
|
-
*/
|
|
476
|
-
async generateText(prompt, options = {}, attemptedProviders = new Set()) {
|
|
477
|
-
const spinnerCallback = options.spinnerCallback;
|
|
478
|
-
const provider = await this.getBestProvider(attemptedProviders);
|
|
479
|
-
const timeout = options.timeout || 180000; // 3 minute timeout for reasoning models like DeepSeek R1
|
|
480
|
-
if (!provider) {
|
|
481
|
-
// No providers available - fail cleanly
|
|
482
|
-
console.log(chalk_1.default.red("❌ No AI providers available"));
|
|
483
|
-
console.log(chalk_1.default.yellow("💡 Configure API keys and retry"));
|
|
484
|
-
throw new Error("No AI providers available - configure API keys and retry");
|
|
485
|
-
}
|
|
486
|
-
// Check if we've already attempted this provider (prevent infinite loop)
|
|
487
|
-
if (attemptedProviders.has(provider.name)) {
|
|
488
|
-
console.log(chalk_1.default.red(`❌ Already attempted provider: ${provider.name}`));
|
|
489
|
-
throw new Error(`All AI providers exhausted. Attempted: ${Array.from(attemptedProviders).join(", ")}`);
|
|
490
|
-
}
|
|
491
|
-
// Safety check: maximum attempts
|
|
492
|
-
if (attemptedProviders.size >= this.providers.length) {
|
|
493
|
-
console.log(chalk_1.default.red(`❌ Maximum provider attempts reached (${attemptedProviders.size}/${this.providers.length})`));
|
|
494
|
-
throw new Error(`All ${this.providers.length} AI providers failed. Attempted: ${Array.from(attemptedProviders).join(", ")}`);
|
|
495
|
-
}
|
|
496
|
-
try {
|
|
497
|
-
let text;
|
|
498
|
-
// Wrap each provider call with timeout
|
|
499
|
-
const providerCall = async () => {
|
|
500
|
-
if (provider.name === "qwen") {
|
|
501
|
-
const qwenClient = provider.client;
|
|
502
|
-
return await qwenClient.generateText(prompt, options);
|
|
503
|
-
}
|
|
504
|
-
else if (provider.name === "github") {
|
|
505
|
-
const githubClient = provider.client;
|
|
506
|
-
return await githubClient.generateText(prompt, options);
|
|
507
|
-
}
|
|
508
|
-
else if (provider.name === "openai") {
|
|
509
|
-
const openaiClient = provider.client;
|
|
510
|
-
return await openaiClient.generateText(prompt, options);
|
|
511
|
-
}
|
|
512
|
-
else if (provider.name === "claude") {
|
|
513
|
-
const claudeClient = provider.client;
|
|
514
|
-
return await claudeClient.generateText(prompt, options);
|
|
515
|
-
}
|
|
516
|
-
else if (provider.name === "huggingface") {
|
|
517
|
-
const hfClient = provider.client;
|
|
518
|
-
return await hfClient.generateComponent(prompt, options);
|
|
519
|
-
}
|
|
520
|
-
else if (provider.name === "gemini") {
|
|
521
|
-
const geminiClient = provider.client;
|
|
522
|
-
const response = await geminiClient.generateText(prompt, options);
|
|
523
|
-
return response.text;
|
|
524
|
-
}
|
|
525
|
-
else if (provider.name === "xai") {
|
|
526
|
-
const xaiClient = provider.client;
|
|
527
|
-
const modelName = await this.getActiveTextModelName();
|
|
528
|
-
return await xaiClient.generateText(prompt, {
|
|
529
|
-
...options,
|
|
530
|
-
model: modelName,
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
else if (provider.name === "openrouter") {
|
|
534
|
-
const openRouterClient = provider.client;
|
|
535
|
-
return await openRouterClient.generateText(prompt, options);
|
|
536
|
-
}
|
|
537
|
-
else if (provider.name === "hosted") {
|
|
538
|
-
const hostedClient = provider.client;
|
|
539
|
-
const response = await hostedClient.generateText(prompt, options);
|
|
540
|
-
if (response.success && response.content) {
|
|
541
|
-
return response.content;
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
throw new Error(response.error || "Hosted API generation failed");
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
else {
|
|
548
|
-
// No fallback - fail cleanly
|
|
549
|
-
throw new Error("AI generation failed - no fallbacks allowed");
|
|
550
|
-
}
|
|
551
|
-
};
|
|
552
|
-
// Execute with timeout
|
|
553
|
-
text = await Promise.race([
|
|
554
|
-
providerCall(),
|
|
555
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${timeout}ms`)), timeout)),
|
|
556
|
-
]);
|
|
557
|
-
return { text, provider: provider.name };
|
|
558
|
-
}
|
|
559
|
-
catch (error) {
|
|
560
|
-
console.log(chalk_1.default.yellow(`[HybridAIClient] Provider ${provider.name} failed: ${error.message}`));
|
|
561
|
-
// Mark this provider as attempted
|
|
562
|
-
attemptedProviders.add(provider.name);
|
|
563
|
-
// Check for remaining providers
|
|
564
|
-
const remainingProviders = this.providers
|
|
565
|
-
.filter(p => !attemptedProviders.has(p.name))
|
|
566
|
-
.map(p => p.name);
|
|
567
|
-
if (remainingProviders.length > 0) {
|
|
568
|
-
console.log(chalk_1.default.blue(`[HybridAIClient] Retrying with next available provider: ${remainingProviders[0]} (remaining: ${remainingProviders.join(", ")})`));
|
|
569
|
-
return this.generateText(prompt, options, attemptedProviders);
|
|
570
|
-
}
|
|
571
|
-
else {
|
|
572
|
-
console.log(chalk_1.default.red(`[HybridAIClient] No more AI providers available (attempted: ${Array.from(attemptedProviders).join(", ")})`));
|
|
573
|
-
throw error;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
43
|
+
async generateComponentRefinement(componentCode, prompt, options = {}) {
|
|
44
|
+
const result = await this.client.generateComponentRefinement(componentCode, prompt, undefined, options);
|
|
45
|
+
const { code, explanation } = this.parseAIResponse(result);
|
|
46
|
+
return { code, provider: await this.getActiveProviderName(), explanation };
|
|
576
47
|
}
|
|
577
|
-
/**
|
|
578
|
-
* Parse AI response to separate code from explanation
|
|
579
|
-
* Enhanced with better pattern matching and truncation handling
|
|
580
|
-
*/
|
|
581
48
|
parseAIResponse(response) {
|
|
582
|
-
|
|
583
|
-
console.log(`🔍 DEBUG: Response preview: ${response.substring(0, 200)}...`);
|
|
584
|
-
// Check if response is truncated (common issue)
|
|
585
|
-
if (response.length < 100) {
|
|
586
|
-
console.warn(`⚠️ WARNING: Response appears truncated (${response.length} chars)`);
|
|
587
|
-
}
|
|
588
|
-
// Enhanced code block detection - look for any code block markers
|
|
49
|
+
// Reuse the parsing logic from old client for compatibility
|
|
589
50
|
const codeBlockPatterns = [
|
|
590
51
|
/```(?:tsx|jsx|ts|js|typescript|javascript)?\s*\n([\s\S]*?)```/g,
|
|
591
52
|
/```(?:tsx|jsx|ts|js|typescript|javascript)?\s*([\s\S]*?)```/g,
|
|
@@ -595,194 +56,14 @@ class HybridAIClient {
|
|
|
595
56
|
for (const pattern of codeBlockPatterns) {
|
|
596
57
|
const matches = [...response.matchAll(pattern)];
|
|
597
58
|
if (matches.length > 0) {
|
|
598
|
-
// Use the longest match (most complete code)
|
|
599
59
|
const longestMatch = matches.reduce((longest, match) => (match[1]?.length || 0) > (longest[1]?.length || 0) ? match : longest);
|
|
600
60
|
const code = longestMatch[1]?.trim() || "";
|
|
601
61
|
const explanation = response.replace(longestMatch[0], "").trim();
|
|
602
|
-
|
|
603
|
-
return {
|
|
604
|
-
code,
|
|
605
|
-
explanation: explanation || undefined,
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
// Enhanced JSX/TSX content detection
|
|
610
|
-
const jsxPatterns = [
|
|
611
|
-
// Complete component with imports
|
|
612
|
-
/(?:import\s+.*?;\s*)*\s*(?:export\s+)?(?:function|const)\s+\w+.*?{[\s\S]*?}(?:\s*export\s+default\s+\w+;?)?/g,
|
|
613
|
-
// Function/const component
|
|
614
|
-
/(?:export\s+)?(?:function|const)\s+\w+.*?{[\s\S]*?}/g,
|
|
615
|
-
// Class component
|
|
616
|
-
/(?:export\s+)?class\s+\w+.*?{[\s\S]*?}/g,
|
|
617
|
-
// Interface/type definitions
|
|
618
|
-
/(?:export\s+)?(?:interface|type)\s+\w+.*?{[\s\S]*?}/g,
|
|
619
|
-
];
|
|
620
|
-
for (const pattern of jsxPatterns) {
|
|
621
|
-
const matches = [...response.matchAll(pattern)];
|
|
622
|
-
if (matches.length > 0) {
|
|
623
|
-
// Use the longest match (most complete code)
|
|
624
|
-
const longestMatch = matches.reduce((longest, match) => match[0].length > longest[0].length ? match : longest);
|
|
625
|
-
const code = longestMatch[0].trim();
|
|
626
|
-
const explanation = response.replace(longestMatch[0], "").trim();
|
|
627
|
-
console.log(`✅ DEBUG: Found JSX/TSX content (${code.length} chars)`);
|
|
628
|
-
return {
|
|
629
|
-
code,
|
|
630
|
-
explanation: explanation || undefined,
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
// Look for incomplete code that might be truncated
|
|
635
|
-
const incompletePatterns = [
|
|
636
|
-
// Incomplete function/const
|
|
637
|
-
/(?:export\s+)?(?:function|const)\s+\w+.*?{[\s\S]*$/,
|
|
638
|
-
// Incomplete import statements
|
|
639
|
-
/import\s+.*?$/,
|
|
640
|
-
// Incomplete interface/type
|
|
641
|
-
/(?:export\s+)?(?:interface|type)\s+\w+.*?{[\s\S]*$/,
|
|
642
|
-
];
|
|
643
|
-
for (const pattern of incompletePatterns) {
|
|
644
|
-
const match = response.match(pattern);
|
|
645
|
-
if (match) {
|
|
646
|
-
console.warn(`⚠️ WARNING: Found incomplete code pattern (${match[0].length} chars)`);
|
|
647
|
-
console.warn(`⚠️ WARNING: This suggests the response was truncated`);
|
|
648
|
-
// Try to complete the incomplete code
|
|
649
|
-
let code = match[0].trim();
|
|
650
|
-
// If it ends with an incomplete function, try to close it
|
|
651
|
-
if (code.includes("{") && !code.includes("}")) {
|
|
652
|
-
code +=
|
|
653
|
-
"\n // TODO: Complete this component - response was truncated\n return <div>Incomplete component</div>;\n}";
|
|
654
|
-
}
|
|
655
|
-
return {
|
|
656
|
-
code,
|
|
657
|
-
explanation: "⚠️ WARNING: Response appears to be truncated. Please retry with a different model or increase token limits.",
|
|
658
|
-
};
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
// If no patterns match, return the whole response as code
|
|
662
|
-
console.log(`⚠️ WARNING: No code patterns found, returning full response as code`);
|
|
663
|
-
return { code: response };
|
|
664
|
-
}
|
|
665
|
-
/**
|
|
666
|
-
* Get provider status
|
|
667
|
-
*/
|
|
668
|
-
async getProviderStatus() {
|
|
669
|
-
const status = [];
|
|
670
|
-
for (const provider of this.providers) {
|
|
671
|
-
try {
|
|
672
|
-
const available = await provider.isAvailable();
|
|
673
|
-
status.push({
|
|
674
|
-
name: provider.name,
|
|
675
|
-
available,
|
|
676
|
-
priority: provider.priority,
|
|
677
|
-
});
|
|
62
|
+
return { code, explanation: explanation || undefined };
|
|
678
63
|
}
|
|
679
|
-
catch (error) {
|
|
680
|
-
status.push({
|
|
681
|
-
name: provider.name,
|
|
682
|
-
available: false,
|
|
683
|
-
priority: provider.priority,
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
return status;
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Set Hugging Face API key
|
|
691
|
-
*/
|
|
692
|
-
setHuggingFaceApiKey(apiKey) {
|
|
693
|
-
const huggingFaceProvider = this.providers.find((p) => p.name === "huggingface");
|
|
694
|
-
if (huggingFaceProvider) {
|
|
695
|
-
huggingFaceProvider.client.setApiKey(apiKey);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* Set OpenAI API key
|
|
700
|
-
*/
|
|
701
|
-
setOpenAIApiKey(apiKey) {
|
|
702
|
-
const openaiProvider = this.providers.find((p) => p.name === "openai");
|
|
703
|
-
if (openaiProvider) {
|
|
704
|
-
openaiProvider.client.setApiKey(apiKey);
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
/**
|
|
708
|
-
* Set Claude API key
|
|
709
|
-
*/
|
|
710
|
-
setClaudeApiKey(apiKey) {
|
|
711
|
-
const claudeProvider = this.providers.find((p) => p.name === "claude");
|
|
712
|
-
if (claudeProvider) {
|
|
713
|
-
claudeProvider.client.setApiKey(apiKey);
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Set Gemini API key
|
|
718
|
-
*/
|
|
719
|
-
setGeminiApiKey(apiKey) {
|
|
720
|
-
const geminiProvider = this.providers.find((p) => p.name === "gemini");
|
|
721
|
-
if (geminiProvider) {
|
|
722
|
-
geminiProvider.client.setApiKey(apiKey);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
async getAvailableProviders() {
|
|
726
|
-
return this.providers;
|
|
727
|
-
}
|
|
728
|
-
async getAllProviders() {
|
|
729
|
-
return this.providers;
|
|
730
|
-
}
|
|
731
|
-
/**
|
|
732
|
-
* Set Claude Agent API key
|
|
733
|
-
*/
|
|
734
|
-
setClaudeAgentApiKey(apiKey) {
|
|
735
|
-
const claudeAgentProvider = this.providers.find((p) => p.name === "claude-agent");
|
|
736
|
-
if (claudeAgentProvider) {
|
|
737
|
-
claudeAgentProvider.client.setApiKey(apiKey);
|
|
738
64
|
}
|
|
739
|
-
|
|
740
|
-
/**
|
|
741
|
-
* Generate component using Claude Agent SDK with enhanced context
|
|
742
|
-
*/
|
|
743
|
-
async generateComponentWithAgent(prompt, context = {}, options = {}) {
|
|
744
|
-
const claudeAgentProvider = this.providers.find((p) => p.name === "claude-agent");
|
|
745
|
-
if (claudeAgentProvider && (await claudeAgentProvider.isAvailable())) {
|
|
746
|
-
const agentClient = claudeAgentProvider.client;
|
|
747
|
-
return await agentClient.generateComponent(prompt, context, options);
|
|
748
|
-
}
|
|
749
|
-
// Fallback to regular component generation
|
|
750
|
-
const result = await this.generateComponent(prompt, options);
|
|
751
|
-
return typeof result === "string" ? result : result.code;
|
|
752
|
-
}
|
|
753
|
-
/**
|
|
754
|
-
* Run agent workflow with Claude Agent SDK
|
|
755
|
-
*/
|
|
756
|
-
async runAgentWorkflow(workflowPrompt, context = {}, options = {}) {
|
|
757
|
-
const claudeAgentProvider = this.providers.find((p) => p.name === "claude-agent");
|
|
758
|
-
if (claudeAgentProvider && (await claudeAgentProvider.isAvailable())) {
|
|
759
|
-
const agentClient = claudeAgentProvider.client;
|
|
760
|
-
return await agentClient.runAgentWorkflow(workflowPrompt, context, options);
|
|
761
|
-
}
|
|
762
|
-
// Fallback to regular text generation
|
|
763
|
-
const result = await this.generateText(workflowPrompt, options);
|
|
764
|
-
const content = typeof result === "string" ? result : result.text;
|
|
765
|
-
return { content, context };
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Check if Claude Agent SDK is available
|
|
769
|
-
*/
|
|
770
|
-
async isClaudeAgentAvailable() {
|
|
771
|
-
const claudeAgentProvider = this.providers.find((p) => p.name === "claude-agent");
|
|
772
|
-
return claudeAgentProvider
|
|
773
|
-
? await claudeAgentProvider.isAvailable()
|
|
774
|
-
: false;
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Get Claude Agent SDK client if available
|
|
778
|
-
*/
|
|
779
|
-
getClaudeAgentClient() {
|
|
780
|
-
const claudeAgentProvider = this.providers.find((p) => p.name === "claude-agent");
|
|
781
|
-
return claudeAgentProvider
|
|
782
|
-
? claudeAgentProvider.client
|
|
783
|
-
: null;
|
|
65
|
+
return { code: response.trim() };
|
|
784
66
|
}
|
|
785
67
|
}
|
|
786
68
|
exports.HybridAIClient = HybridAIClient;
|
|
787
|
-
HybridAIClient.hasLoggedInitialization = false;
|
|
788
69
|
//# sourceMappingURL=hybridAIClient.js.map
|