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/README.md +226 -0
- package/dist/analyzer.d.ts +58 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +203 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +442 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +28 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +118 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.d.ts +71 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +315 -0
- package/dist/executor.js.map +1 -0
- package/dist/index.d.ts +126 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +19 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +336 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/models.d.ts +101 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.js +202 -0
- package/dist/models.js.map +1 -0
- package/dist/orchestrator.d.ts +61 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +325 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/prompts.d.ts +48 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +220 -0
- package/dist/prompts.js.map +1 -0
- package/dist/types.d.ts +125 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +87 -0
- package/dist/types.js.map +1 -0
- package/package.json +77 -0
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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"}
|