rlm-analyzer 1.1.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/dist/models.js ADDED
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Model Configuration Module
3
+ * Handles model resolution with configurable priority chain
4
+ *
5
+ * Priority chain for model resolution:
6
+ * 1. CLI --model flag (highest)
7
+ * 2. Environment variables: RLM_DEFAULT_MODEL, RLM_FALLBACK_MODEL
8
+ * 3. Config file: ~/.rlm-analyzer/config.json
9
+ * 4. Programmatic API: createAnalyzer({ model: '...' })
10
+ * 5. Built-in defaults (lowest, internal only)
11
+ */
12
+ import * as fs from 'fs';
13
+ import * as path from 'path';
14
+ import * as os from 'os';
15
+ // ============================================================================
16
+ // Private built-in defaults (not exported)
17
+ // ============================================================================
18
+ const BUILTIN_DEFAULT_MODEL = 'gemini-3-flash-preview';
19
+ const BUILTIN_FALLBACK_MODEL = 'gemini-3-flash-preview';
20
+ // ============================================================================
21
+ // Model Aliases
22
+ // ============================================================================
23
+ /**
24
+ * Model aliases for convenience
25
+ * Users can specify aliases instead of full model IDs
26
+ */
27
+ export const MODEL_ALIASES = {
28
+ fast: 'gemini-3-flash-preview',
29
+ smart: 'gemini-3-pro-preview',
30
+ default: 'gemini-3-flash-preview',
31
+ pro: 'gemini-3-pro-preview',
32
+ flash: 'gemini-3-flash-preview',
33
+ 'flash-2': 'gemini-2.0-flash-exp',
34
+ 'flash-2.5': 'gemini-2.5-flash',
35
+ };
36
+ /**
37
+ * Available model options (for display in help)
38
+ */
39
+ export const AVAILABLE_MODELS = [
40
+ { id: 'gemini-3-flash-preview', description: 'Gemini 3 Flash - Fast and efficient' },
41
+ { id: 'gemini-3-pro-preview', description: 'Gemini 3 Pro - Most capable' },
42
+ { id: 'gemini-2.5-flash', description: 'Gemini 2.5 Flash - Stable' },
43
+ { id: 'gemini-2.0-flash-exp', description: 'Gemini 2.0 Flash - Fallback' },
44
+ ];
45
+ /**
46
+ * Read model configuration from config file
47
+ */
48
+ function readConfigFile() {
49
+ const configPaths = [
50
+ path.join(os.homedir(), '.rlm-analyzer', 'config.json'),
51
+ path.join(os.homedir(), '.config', 'rlm-analyzer', 'config.json'),
52
+ ];
53
+ for (const configPath of configPaths) {
54
+ if (fs.existsSync(configPath)) {
55
+ try {
56
+ return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
57
+ }
58
+ catch {
59
+ // Ignore parse errors
60
+ }
61
+ }
62
+ }
63
+ return null;
64
+ }
65
+ // ============================================================================
66
+ // Model Alias Resolution
67
+ // ============================================================================
68
+ /**
69
+ * Resolve a model alias to its full model ID
70
+ * If the input is not an alias, returns it unchanged
71
+ *
72
+ * @param modelOrAlias - Model ID or alias
73
+ * @returns Full model ID
74
+ */
75
+ export function resolveModelAlias(modelOrAlias) {
76
+ const lowercased = modelOrAlias.toLowerCase();
77
+ return MODEL_ALIASES[lowercased] || modelOrAlias;
78
+ }
79
+ /**
80
+ * Check if a string is a known model alias
81
+ */
82
+ export function isModelAlias(value) {
83
+ return value.toLowerCase() in MODEL_ALIASES;
84
+ }
85
+ // ============================================================================
86
+ // Main Resolution Functions
87
+ // ============================================================================
88
+ /**
89
+ * Resolve full model configuration using priority chain
90
+ *
91
+ * Priority:
92
+ * 1. CLI/API options (highest)
93
+ * 2. Environment variables: RLM_DEFAULT_MODEL, RLM_FALLBACK_MODEL
94
+ * 3. Config file: ~/.rlm-analyzer/config.json
95
+ * 4. Built-in defaults (lowest)
96
+ *
97
+ * @param options - Optional overrides from CLI or programmatic API
98
+ * @returns Resolved model configuration with source information
99
+ */
100
+ export function resolveModelConfig(options = {}) {
101
+ let defaultModel = BUILTIN_DEFAULT_MODEL;
102
+ let fallbackModel = BUILTIN_FALLBACK_MODEL;
103
+ let defaultSource = 'builtin';
104
+ let fallbackSource = 'builtin';
105
+ // Step 1: Start with config file (lowest priority after builtin)
106
+ const configFile = readConfigFile();
107
+ if (configFile) {
108
+ const configDefault = configFile.models?.default;
109
+ const configFallback = configFile.models?.fallback;
110
+ if (configDefault) {
111
+ defaultModel = resolveModelAlias(configDefault);
112
+ defaultSource = 'config';
113
+ }
114
+ if (configFallback) {
115
+ fallbackModel = resolveModelAlias(configFallback);
116
+ fallbackSource = 'config';
117
+ }
118
+ }
119
+ // Step 2: Check environment variables (higher priority)
120
+ const envDefault = process.env.RLM_DEFAULT_MODEL;
121
+ const envFallback = process.env.RLM_FALLBACK_MODEL;
122
+ if (envDefault) {
123
+ defaultModel = resolveModelAlias(envDefault);
124
+ defaultSource = 'env';
125
+ }
126
+ if (envFallback) {
127
+ fallbackModel = resolveModelAlias(envFallback);
128
+ fallbackSource = 'env';
129
+ }
130
+ // Step 3: Apply CLI/API options (highest priority)
131
+ if (options.model) {
132
+ defaultModel = resolveModelAlias(options.model);
133
+ defaultSource = 'cli';
134
+ }
135
+ if (options.fallbackModel) {
136
+ fallbackModel = resolveModelAlias(options.fallbackModel);
137
+ fallbackSource = 'cli';
138
+ }
139
+ return {
140
+ defaultModel,
141
+ fallbackModel,
142
+ defaultSource,
143
+ fallbackSource,
144
+ };
145
+ }
146
+ /**
147
+ * Get the default model ID using the priority chain
148
+ * Convenience function for getting just the default model
149
+ *
150
+ * @param options - Optional overrides
151
+ * @returns Resolved default model ID
152
+ */
153
+ export function getDefaultModel(options = {}) {
154
+ return resolveModelConfig(options).defaultModel;
155
+ }
156
+ /**
157
+ * Get the fallback model ID using the priority chain
158
+ * Convenience function for getting just the fallback model
159
+ *
160
+ * @param options - Optional overrides
161
+ * @returns Resolved fallback model ID
162
+ */
163
+ export function getFallbackModel(options = {}) {
164
+ return resolveModelConfig(options).fallbackModel;
165
+ }
166
+ // ============================================================================
167
+ // Backward Compatibility Exports
168
+ // ============================================================================
169
+ /**
170
+ * @deprecated Use `getDefaultModel()` instead for dynamic resolution
171
+ * This is computed at import time and won't reflect runtime changes
172
+ */
173
+ export const DEFAULT_MODEL = getDefaultModel();
174
+ /**
175
+ * @deprecated Use `getFallbackModel()` instead for dynamic resolution
176
+ * This is computed at import time and won't reflect runtime changes
177
+ */
178
+ export const FALLBACK_MODEL = getFallbackModel();
179
+ // ============================================================================
180
+ // Display Helpers
181
+ // ============================================================================
182
+ /**
183
+ * Get formatted string showing current model configuration
184
+ * Useful for CLI help text and debugging
185
+ */
186
+ export function getModelConfigDisplay(options = {}) {
187
+ const config = resolveModelConfig(options);
188
+ const lines = [
189
+ `Default Model: ${config.defaultModel} (from ${config.defaultSource})`,
190
+ `Fallback Model: ${config.fallbackModel} (from ${config.fallbackSource})`,
191
+ ];
192
+ return lines.join('\n');
193
+ }
194
+ /**
195
+ * Get formatted string showing available aliases
196
+ * Useful for CLI help text
197
+ */
198
+ export function getAliasesDisplay() {
199
+ const lines = Object.entries(MODEL_ALIASES).map(([alias, model]) => ` ${alias.padEnd(12)} → ${model}`);
200
+ return lines.join('\n');
201
+ }
202
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * RLM Orchestrator
3
+ * Manages the conversation loop between model and REPL
4
+ * Uses Gemini 3 Flash via @google/genai SDK
5
+ */
6
+ import type { RLMConfig, RLMContext, RLMResult, RLMTurn } from './types.js';
7
+ /**
8
+ * RLM Orchestrator manages the agentic loop
9
+ */
10
+ /**
11
+ * Thresholds for minimum sub-LLM calls based on codebase size
12
+ * These can be adjusted to tune analysis depth vs speed
13
+ */
14
+ export declare const SUB_LLM_THRESHOLDS: {
15
+ /** Files >= 200: require at least 5 sub-LLM calls */
16
+ readonly VERY_LARGE: {
17
+ readonly files: 200;
18
+ readonly minCalls: 5;
19
+ };
20
+ /** Files >= 100: require at least 4 sub-LLM calls */
21
+ readonly LARGE: {
22
+ readonly files: 100;
23
+ readonly minCalls: 4;
24
+ };
25
+ /** Files >= 50: require at least 3 sub-LLM calls */
26
+ readonly MEDIUM: {
27
+ readonly files: 50;
28
+ readonly minCalls: 3;
29
+ };
30
+ /** Files >= 20: require at least 2 sub-LLM calls */
31
+ readonly SMALL: {
32
+ readonly files: 20;
33
+ readonly minCalls: 2;
34
+ };
35
+ /** Default minimum for tiny codebases */
36
+ readonly DEFAULT_MIN: 1;
37
+ };
38
+ export declare class RLMOrchestrator {
39
+ private config;
40
+ private executor;
41
+ private verbose;
42
+ private fallbackModel;
43
+ constructor(config?: Partial<RLMConfig>, verbose?: boolean);
44
+ /**
45
+ * Process a query with the RLM system
46
+ */
47
+ processQuery(query: string, context: RLMContext, onTurnComplete?: (turn: RLMTurn) => void): Promise<RLMResult>;
48
+ /**
49
+ * Call model with conversation history using Gemini
50
+ */
51
+ private callConversation;
52
+ /**
53
+ * Call model with single prompt using Gemini with fallback
54
+ */
55
+ private callModel;
56
+ /**
57
+ * Extract code from response
58
+ */
59
+ private extractCode;
60
+ }
61
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,OAAO,EACR,MAAM,YAAY,CAAC;AAOpB;;GAEG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC7B,qDAAqD;;;;;IAErD,qDAAqD;;;;;IAErD,oDAAoD;;;;;IAEpD,oDAAoD;;;;;IAEpD,yCAAyC;;CAEjC,CAAC;AAcX,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,aAAa,CAAS;gBAElB,MAAM,GAAE,OAAO,CAAC,SAAS,CAAM,EAAE,OAAO,UAAQ;IAmB5D;;OAEG;IACG,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,UAAU,EACnB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GACvC,OAAO,CAAC,SAAS,CAAC;IAoMrB;;OAEG;YACW,gBAAgB;IAgD9B;;OAEG;YACW,SAAS;IAuCvB;;OAEG;IACH,OAAO,CAAC,WAAW;CAIpB"}
@@ -0,0 +1,325 @@
1
+ /**
2
+ * RLM Orchestrator
3
+ * Manages the conversation loop between model and REPL
4
+ * Uses Gemini 3 Flash via @google/genai SDK
5
+ */
6
+ import { RLMExecutor } from './executor.js';
7
+ import { getAIClient } from './config.js';
8
+ import { getDefaultModel, getFallbackModel } from './models.js';
9
+ import { getSystemPrompt, buildContextMessage } from './prompts.js';
10
+ /**
11
+ * RLM Orchestrator manages the agentic loop
12
+ */
13
+ /**
14
+ * Thresholds for minimum sub-LLM calls based on codebase size
15
+ * These can be adjusted to tune analysis depth vs speed
16
+ */
17
+ export const SUB_LLM_THRESHOLDS = {
18
+ /** Files >= 200: require at least 5 sub-LLM calls */
19
+ VERY_LARGE: { files: 200, minCalls: 5 },
20
+ /** Files >= 100: require at least 4 sub-LLM calls */
21
+ LARGE: { files: 100, minCalls: 4 },
22
+ /** Files >= 50: require at least 3 sub-LLM calls */
23
+ MEDIUM: { files: 50, minCalls: 3 },
24
+ /** Files >= 20: require at least 2 sub-LLM calls */
25
+ SMALL: { files: 20, minCalls: 2 },
26
+ /** Default minimum for tiny codebases */
27
+ DEFAULT_MIN: 1,
28
+ };
29
+ /**
30
+ * Calculate minimum required sub-LLM calls based on file count
31
+ * Larger codebases require more recursive analysis for quality results
32
+ */
33
+ function getMinSubLLMCalls(fileCount) {
34
+ if (fileCount >= SUB_LLM_THRESHOLDS.VERY_LARGE.files)
35
+ return SUB_LLM_THRESHOLDS.VERY_LARGE.minCalls;
36
+ if (fileCount >= SUB_LLM_THRESHOLDS.LARGE.files)
37
+ return SUB_LLM_THRESHOLDS.LARGE.minCalls;
38
+ if (fileCount >= SUB_LLM_THRESHOLDS.MEDIUM.files)
39
+ return SUB_LLM_THRESHOLDS.MEDIUM.minCalls;
40
+ if (fileCount >= SUB_LLM_THRESHOLDS.SMALL.files)
41
+ return SUB_LLM_THRESHOLDS.SMALL.minCalls;
42
+ return SUB_LLM_THRESHOLDS.DEFAULT_MIN;
43
+ }
44
+ export class RLMOrchestrator {
45
+ config;
46
+ executor;
47
+ verbose;
48
+ fallbackModel;
49
+ constructor(config = {}, verbose = false) {
50
+ // Resolve models dynamically using the priority chain
51
+ const defaultModel = getDefaultModel({ model: config.rootModel });
52
+ const fallback = getFallbackModel();
53
+ this.config = {
54
+ rootModel: config.rootModel || defaultModel,
55
+ subModel: config.subModel || defaultModel,
56
+ maxRecursionDepth: config.maxRecursionDepth || 3,
57
+ maxTurns: config.maxTurns || 10,
58
+ timeoutMs: config.timeoutMs || 300000,
59
+ maxSubCalls: config.maxSubCalls || 15,
60
+ mode: config.mode || 'code-analysis',
61
+ };
62
+ this.fallbackModel = fallback;
63
+ this.executor = new RLMExecutor(this.config.maxSubCalls);
64
+ this.verbose = verbose;
65
+ }
66
+ /**
67
+ * Process a query with the RLM system
68
+ */
69
+ async processQuery(query, context, onTurnComplete) {
70
+ const startTime = Date.now();
71
+ const turns = [];
72
+ // Initialize executor with files
73
+ this.executor.initialize(context.files);
74
+ // Set up sub-LLM callback
75
+ this.executor.setSubLLMCallback(async (subQuery) => {
76
+ if (this.verbose) {
77
+ console.log(` [Sub-LLM] ${subQuery.slice(0, 60)}...`);
78
+ }
79
+ return this.callModel(this.config.subModel, subQuery, 0.3, 2048);
80
+ });
81
+ // Build initial messages
82
+ const systemPrompt = getSystemPrompt(this.config.mode);
83
+ const contextMessage = buildContextMessage(Object.keys(context.files).length, Object.keys(context.files), query);
84
+ const history = [
85
+ { role: 'user', parts: [{ text: `${systemPrompt}\n\n${contextMessage}` }] },
86
+ ];
87
+ // Main conversation loop
88
+ for (let turn = 1; turn <= this.config.maxTurns; turn++) {
89
+ // Check timeout
90
+ if (Date.now() - startTime > this.config.timeoutMs) {
91
+ return {
92
+ success: false,
93
+ answer: null,
94
+ turns,
95
+ executionTimeMs: Date.now() - startTime,
96
+ subCallCount: this.executor.getSubCallCount(),
97
+ error: 'Timeout exceeded',
98
+ };
99
+ }
100
+ if (this.verbose) {
101
+ console.log(`\n--- Turn ${turn} ---`);
102
+ }
103
+ // Get model response
104
+ const response = await this.callConversation(history);
105
+ if (this.verbose) {
106
+ console.log(`Response: ${response.slice(0, 150)}...`);
107
+ }
108
+ // Check for code block
109
+ const hasCode = response.includes('```');
110
+ let executionResult = null;
111
+ let executionError = null;
112
+ if (hasCode) {
113
+ if (this.verbose) {
114
+ console.log('Executing code...');
115
+ }
116
+ const result = await this.executor.execute(response);
117
+ if (result.success) {
118
+ executionResult = result.output;
119
+ }
120
+ else {
121
+ executionError = result.error || 'Unknown error';
122
+ }
123
+ if (this.verbose) {
124
+ const preview = (executionResult || executionError || '').slice(0, 150);
125
+ console.log(`Output: ${preview}...`);
126
+ }
127
+ history.push({ role: 'model', parts: [{ text: response }] });
128
+ history.push({
129
+ role: 'user',
130
+ parts: [{
131
+ text: result.success
132
+ ? `Result:\n\`\`\`\n${executionResult}\n\`\`\``
133
+ : `Error:\n\`\`\`\n${executionError}\n\`\`\`\n\nPlease fix the code and try again.`,
134
+ }],
135
+ });
136
+ }
137
+ else {
138
+ // No code, prompt for code or FINAL
139
+ history.push({ role: 'model', parts: [{ text: response }] });
140
+ history.push({
141
+ role: 'user',
142
+ parts: [{
143
+ text: 'Please write Python code to analyze the codebase, or use FINAL("your answer") if you have the answer.',
144
+ }],
145
+ });
146
+ }
147
+ // Create turn record
148
+ const turnRecord = {
149
+ turn,
150
+ response,
151
+ code: hasCode ? this.extractCode(response) : null,
152
+ executionResult,
153
+ error: executionError,
154
+ timestamp: Date.now(),
155
+ };
156
+ turns.push(turnRecord);
157
+ if (onTurnComplete) {
158
+ onTurnComplete(turnRecord);
159
+ }
160
+ // Check for final answer - but enforce minimum sub-LLM calls first
161
+ const fileCount = Object.keys(context.files).length;
162
+ const minSubCalls = getMinSubLLMCalls(fileCount);
163
+ const currentSubCalls = this.executor.getSubCallCount();
164
+ const needsMoreSubCalls = currentSubCalls < minSubCalls;
165
+ if (this.executor.hasFinalAnswer()) {
166
+ if (needsMoreSubCalls) {
167
+ // Reject the final answer and ask for more sub-LLM analysis
168
+ if (this.verbose) {
169
+ console.log(` [RLM] Insufficient sub-LLM calls: ${currentSubCalls}/${minSubCalls} required`);
170
+ }
171
+ this.executor.clearFinalAnswer();
172
+ history.push({ role: 'model', parts: [{ text: response }] });
173
+ history.push({
174
+ role: 'user',
175
+ parts: [{
176
+ text: `⚠️ INSUFFICIENT ANALYSIS: You made only ${currentSubCalls} sub-LLM calls, but this codebase (${fileCount} files) requires at least ${minSubCalls} llm_query() calls for quality analysis.
177
+
178
+ Your FINAL() was rejected. You MUST use llm_query() to analyze more files before providing your final answer.
179
+
180
+ Suggested files to analyze with llm_query():
181
+ - Entry points (index.ts, main.ts, App.tsx)
182
+ - Config files (package.json, tsconfig.json)
183
+ - Core services or modules
184
+ - Type definitions
185
+
186
+ Example:
187
+ \`\`\`python
188
+ analysis = llm_query(f"Analyze this file for architecture patterns:\\n{file_index['src/index.ts'][:3000]}")
189
+ print(analysis)
190
+ \`\`\`
191
+
192
+ Make ${minSubCalls - currentSubCalls} more llm_query() calls, then call FINAL() with your comprehensive analysis.`,
193
+ }],
194
+ });
195
+ continue;
196
+ }
197
+ return {
198
+ success: true,
199
+ answer: this.executor.getFinalAnswer(),
200
+ turns,
201
+ executionTimeMs: Date.now() - startTime,
202
+ subCallCount: this.executor.getSubCallCount(),
203
+ };
204
+ }
205
+ // Check for FINAL in response text
206
+ const finalMatch = response.match(/FINAL\s*\(\s*["'`]([\s\S]*?)["'`]\s*\)/);
207
+ if (finalMatch) {
208
+ if (needsMoreSubCalls) {
209
+ // Reject and ask for more analysis
210
+ if (this.verbose) {
211
+ console.log(` [RLM] Insufficient sub-LLM calls: ${currentSubCalls}/${minSubCalls} required`);
212
+ }
213
+ history.push({ role: 'model', parts: [{ text: response }] });
214
+ history.push({
215
+ role: 'user',
216
+ parts: [{
217
+ text: `⚠️ INSUFFICIENT ANALYSIS: You made only ${currentSubCalls} sub-LLM calls, but this codebase (${fileCount} files) requires at least ${minSubCalls} llm_query() calls.
218
+
219
+ Your FINAL() was rejected. Use llm_query() to analyze ${minSubCalls - currentSubCalls} more key files, then provide your final answer.`,
220
+ }],
221
+ });
222
+ continue;
223
+ }
224
+ return {
225
+ success: true,
226
+ answer: finalMatch[1],
227
+ turns,
228
+ executionTimeMs: Date.now() - startTime,
229
+ subCallCount: this.executor.getSubCallCount(),
230
+ };
231
+ }
232
+ }
233
+ // Max turns exceeded
234
+ return {
235
+ success: false,
236
+ answer: null,
237
+ turns,
238
+ executionTimeMs: Date.now() - startTime,
239
+ subCallCount: this.executor.getSubCallCount(),
240
+ error: `Max turns (${this.config.maxTurns}) exceeded. Partial output:\n${this.executor.getOutput()}`,
241
+ };
242
+ }
243
+ /**
244
+ * Call model with conversation history using Gemini
245
+ */
246
+ async callConversation(history) {
247
+ const ai = getAIClient();
248
+ const modelsToTry = [this.config.rootModel];
249
+ // Add fallback model if not already using it
250
+ if (this.config.rootModel !== this.fallbackModel) {
251
+ modelsToTry.push(this.fallbackModel);
252
+ }
253
+ let lastError = null;
254
+ for (const model of modelsToTry) {
255
+ try {
256
+ const response = await ai.models.generateContent({
257
+ model,
258
+ contents: history,
259
+ config: {
260
+ temperature: 0.7,
261
+ maxOutputTokens: 4096,
262
+ },
263
+ });
264
+ // If using fallback and it worked, log it
265
+ if (model !== this.config.rootModel && this.verbose) {
266
+ console.log(` [Info] Using fallback model: ${model}`);
267
+ }
268
+ return response.text || '';
269
+ }
270
+ catch (error) {
271
+ const message = error instanceof Error ? error.message : String(error);
272
+ lastError = new Error(`Model ${model}: ${message}`);
273
+ // If it's a 500 error, try the next model
274
+ if (message.includes('500') || message.includes('Internal')) {
275
+ if (this.verbose) {
276
+ console.log(` [Warning] ${model} returned 500, trying fallback...`);
277
+ }
278
+ continue;
279
+ }
280
+ // For other errors, don't try fallback
281
+ throw new Error(`Gemini API error (model: ${model}): ${message}`);
282
+ }
283
+ }
284
+ throw new Error(`All models failed. Last error: ${lastError?.message}`);
285
+ }
286
+ /**
287
+ * Call model with single prompt using Gemini with fallback
288
+ */
289
+ async callModel(model, prompt, temperature = 0.3, maxTokens = 2048) {
290
+ const ai = getAIClient();
291
+ const modelsToTry = [model];
292
+ if (model !== this.fallbackModel) {
293
+ modelsToTry.push(this.fallbackModel);
294
+ }
295
+ for (const currentModel of modelsToTry) {
296
+ try {
297
+ const response = await ai.models.generateContent({
298
+ model: currentModel,
299
+ contents: prompt,
300
+ config: {
301
+ temperature,
302
+ maxOutputTokens: maxTokens,
303
+ },
304
+ });
305
+ return response.text || '';
306
+ }
307
+ catch (error) {
308
+ const message = error instanceof Error ? error.message : String(error);
309
+ if (message.includes('500') || message.includes('Internal')) {
310
+ continue;
311
+ }
312
+ throw new Error(`Gemini API error (model: ${currentModel}): ${message}`);
313
+ }
314
+ }
315
+ throw new Error('All models failed for sub-LLM call');
316
+ }
317
+ /**
318
+ * Extract code from response
319
+ */
320
+ extractCode(text) {
321
+ const match = text.match(/```(?:python|javascript|tool_code|js|ts)?\n([\s\S]*?)```/);
322
+ return match ? match[1] : null;
323
+ }
324
+ }
325
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"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"}