@juspay/yama 2.3.0 → 2.4.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/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [2.4.0](https://github.com/juspay/yama/compare/v2.3.0...v2.4.0) (2026-04-15)
2
+
3
+
4
+ ### Features
5
+
6
+ * **v2:** bootstrap repo standards from recent PRs before review ([8c5b1cd](https://github.com/juspay/yama/commit/8c5b1cdd38b684397e7445e04b4db4bc45b5f2a8))
7
+
1
8
  # [2.3.0](https://github.com/juspay/yama/compare/v2.2.2...v2.3.0) (2026-04-01)
2
9
 
3
10
 
@@ -180,13 +180,19 @@ export class ConfigLoader {
180
180
  if (process.env.AI_MODEL) {
181
181
  config.ai.model = process.env.AI_MODEL;
182
182
  }
183
- // Override temperature if env var set
183
+ // Override temperature if env var set (ignore non-finite values)
184
184
  if (process.env.AI_TEMPERATURE) {
185
- config.ai.temperature = parseFloat(process.env.AI_TEMPERATURE);
185
+ const temperature = Number(process.env.AI_TEMPERATURE);
186
+ if (Number.isFinite(temperature)) {
187
+ config.ai.temperature = temperature;
188
+ }
186
189
  }
187
- // Override max tokens if env var set
190
+ // Override max tokens if env var set (ignore non-integer / non-positive values)
188
191
  if (process.env.AI_MAX_TOKENS) {
189
- config.ai.maxTokens = parseInt(process.env.AI_MAX_TOKENS, 10);
192
+ const maxTokens = Number.parseInt(process.env.AI_MAX_TOKENS, 10);
193
+ if (Number.isInteger(maxTokens) && maxTokens > 0) {
194
+ config.ai.maxTokens = maxTokens;
195
+ }
190
196
  }
191
197
  if (process.env.AI_ENABLE_TOOL_FILTERING) {
192
198
  config.ai.enableToolFiltering =
@@ -198,6 +204,34 @@ export class ConfigLoader {
198
204
  config.ai.toolFilteringMode = mode;
199
205
  }
200
206
  }
207
+ if (process.env.AI_EXPLORE_ENABLED) {
208
+ config.ai.explore.enabled = process.env.AI_EXPLORE_ENABLED === "true";
209
+ }
210
+ if (process.env.AI_EXPLORE_PROVIDER) {
211
+ config.ai.explore.provider = process.env.AI_EXPLORE_PROVIDER;
212
+ }
213
+ if (process.env.AI_EXPLORE_MODEL) {
214
+ config.ai.explore.model = process.env.AI_EXPLORE_MODEL;
215
+ }
216
+ if (process.env.AI_EXPLORE_TEMPERATURE) {
217
+ const temperature = Number(process.env.AI_EXPLORE_TEMPERATURE);
218
+ if (Number.isFinite(temperature)) {
219
+ config.ai.explore.temperature = temperature;
220
+ }
221
+ }
222
+ if (process.env.AI_EXPLORE_MAX_TOKENS) {
223
+ const maxTokens = Number.parseInt(process.env.AI_EXPLORE_MAX_TOKENS, 10);
224
+ if (Number.isInteger(maxTokens) && maxTokens > 0) {
225
+ config.ai.explore.maxTokens = maxTokens;
226
+ }
227
+ }
228
+ if (process.env.AI_EXPLORE_TIMEOUT) {
229
+ config.ai.explore.timeout = process.env.AI_EXPLORE_TIMEOUT;
230
+ }
231
+ if (process.env.AI_EXPLORE_CACHE_RESULTS) {
232
+ config.ai.explore.cacheResults =
233
+ process.env.AI_EXPLORE_CACHE_RESULTS === "true";
234
+ }
201
235
  return config;
202
236
  }
203
237
  /**
@@ -31,6 +31,15 @@ export class DefaultConfig {
31
31
  maxTurnsPerSession: 300,
32
32
  enableSummarization: false,
33
33
  },
34
+ explore: {
35
+ enabled: true,
36
+ provider: "auto",
37
+ model: "gemini-2.5-flash",
38
+ temperature: 0.1,
39
+ maxTokens: 32000,
40
+ timeout: "5m",
41
+ cacheResults: true,
42
+ },
34
43
  },
35
44
  mcpServers: {
36
45
  bitbucket: {
@@ -2,7 +2,7 @@
2
2
  * Session Manager for Yama
3
3
  * Tracks review sessions, tool calls, and maintains state
4
4
  */
5
- import { ReviewSession, ReviewRequest, ReviewResult, SessionMetadata } from "../types/v2.types.js";
5
+ import { ReviewSession, ReviewRequest, ReviewResult, SessionMetadata, ExplorationResult } from "../types/v2.types.js";
6
6
  export declare class SessionManager {
7
7
  private sessions;
8
8
  private maxSessions;
@@ -22,6 +22,8 @@ export declare class SessionManager {
22
22
  * Update session metadata
23
23
  */
24
24
  updateMetadata(sessionId: string, updates: Partial<SessionMetadata>): void;
25
+ recordExploration(sessionId: string, cacheKey: string, task: string, focus: string[], result: ExplorationResult, cached?: boolean): void;
26
+ findExploration(sessionId: string, cacheKey: string): ExplorationResult | null;
25
27
  /**
26
28
  * Mark session as completed
27
29
  */
@@ -25,6 +25,7 @@ export class SessionManager {
25
25
  totalCost: 0,
26
26
  cacheHitRatio: 0,
27
27
  },
28
+ explorations: [],
28
29
  };
29
30
  this.sessions.set(sessionId, session);
30
31
  // Clean up old sessions if we exceed max
@@ -68,6 +69,26 @@ export class SessionManager {
68
69
  ...updates,
69
70
  };
70
71
  }
72
+ recordExploration(sessionId, cacheKey, task, focus, result, cached = false) {
73
+ const session = this.getSession(sessionId);
74
+ session.explorations = session.explorations || [];
75
+ session.explorations.push({
76
+ task,
77
+ cacheKey,
78
+ focus,
79
+ result,
80
+ createdAt: new Date(),
81
+ cached,
82
+ });
83
+ }
84
+ findExploration(sessionId, cacheKey) {
85
+ const session = this.getSession(sessionId);
86
+ const match = (session.explorations || [])
87
+ .slice()
88
+ .reverse()
89
+ .find((exploration) => exploration.cacheKey === cacheKey);
90
+ return match?.result || null;
91
+ }
71
92
  /**
72
93
  * Mark session as completed
73
94
  */
@@ -166,6 +187,15 @@ export class SessionManager {
166
187
  // Don't include full result in export (can be very large)
167
188
  resultSummary: this.summarizeToolResult(tc.result),
168
189
  })),
190
+ explorations: (session.explorations || []).map((exploration) => ({
191
+ task: exploration.task,
192
+ cacheKey: exploration.cacheKey,
193
+ focus: exploration.focus,
194
+ createdAt: exploration.createdAt.toISOString(),
195
+ cached: exploration.cached,
196
+ // Don't include full result in export (can be very large / may contain sensitive data)
197
+ resultSummary: this.summarizeToolResult(exploration.result),
198
+ })),
169
199
  };
170
200
  }
171
201
  /**
@@ -6,6 +6,7 @@ import { LocalReviewRequest, LocalReviewResult, ReviewRequest, ReviewResult, Rev
6
6
  import { YamaInitOptions } from "../types/config.types.js";
7
7
  export declare class YamaOrchestrator {
8
8
  private neurolink;
9
+ private explorer;
9
10
  private mcpManager;
10
11
  private configLoader;
11
12
  private promptBuilder;
@@ -16,7 +17,10 @@ export declare class YamaOrchestrator {
16
17
  private initialized;
17
18
  private mcpInitialized;
18
19
  private localGitMcpInitialized;
20
+ private exploreToolRegistered;
21
+ private currentToolContext;
19
22
  private initOptions;
23
+ private bootstrapStandardsCache;
20
24
  constructor(options?: YamaInitOptions);
21
25
  /**
22
26
  * Initialize Yama with configuration and MCP servers
@@ -67,6 +71,8 @@ export declare class YamaOrchestrator {
67
71
  exportSession(sessionId: string): any;
68
72
  private getUserId;
69
73
  private createToolContext;
74
+ private createLocalToolContext;
75
+ private setToolContext;
70
76
  /**
71
77
  * Parse AI response into structured review result
72
78
  */
@@ -120,6 +126,14 @@ export declare class YamaOrchestrator {
120
126
  * Initialize NeuroLink with observability configuration
121
127
  */
122
128
  private initializeNeurolink;
129
+ private registerExploreTool;
130
+ /**
131
+ * Bootstrap repo-level standards by delegating to explore_context.
132
+ * Runs once per (workspace/repository) per process lifetime.
133
+ * Output is injected into the review prompt as <bootstrapped-standards>.
134
+ * Graceful: any failure returns empty and the review proceeds without it.
135
+ */
136
+ private getBootstrappedStandards;
123
137
  /**
124
138
  * Ensure orchestrator is initialized
125
139
  */
@@ -9,9 +9,11 @@ import { PromptBuilder } from "../prompts/PromptBuilder.js";
9
9
  import { SessionManager } from "./SessionManager.js";
10
10
  import { MemoryManager } from "../memory/MemoryManager.js";
11
11
  import { LocalDiffSource } from "./LocalDiffSource.js";
12
+ import { ContextExplorerService } from "../exploration/ContextExplorerService.js";
12
13
  import { buildObservabilityConfigFromEnv, validateObservabilityConfig, } from "../utils/ObservabilityConfig.js";
13
14
  export class YamaOrchestrator {
14
15
  neurolink;
16
+ explorer = null;
15
17
  mcpManager;
16
18
  configLoader;
17
19
  promptBuilder;
@@ -22,7 +24,10 @@ export class YamaOrchestrator {
22
24
  initialized = false;
23
25
  mcpInitialized = false;
24
26
  localGitMcpInitialized = false;
27
+ exploreToolRegistered = false;
28
+ currentToolContext = null;
25
29
  initOptions;
30
+ bootstrapStandardsCache = new Map();
26
31
  constructor(options = {}) {
27
32
  this.initOptions = options;
28
33
  this.configLoader = new ConfigLoader();
@@ -50,16 +55,24 @@ export class YamaOrchestrator {
50
55
  // Step 3: Initialize NeuroLink with memory config injected
51
56
  console.log("🧠 Initializing NeuroLink AI engine...");
52
57
  this.neurolink = this.initializeNeurolink();
58
+ this.explorer = new ContextExplorerService(this.config, this.sessionManager, this.memoryManager);
59
+ this.registerExploreTool();
53
60
  console.log("✅ NeuroLink initialized\n");
54
61
  this.initialized = true;
55
62
  }
56
63
  // Step 4: Mode-specific setup
57
64
  if (mode === "pr" && !this.mcpInitialized) {
58
65
  await this.mcpManager.setupMCPServers(this.neurolink, this.config.mcpServers);
66
+ if (this.explorer && this.config.ai.explore.enabled) {
67
+ await this.explorer.initialize("pr");
68
+ }
59
69
  this.mcpInitialized = true;
60
70
  }
61
71
  else if (mode === "local" && !this.localGitMcpInitialized) {
62
72
  await this.mcpManager.setupLocalGitMCPServer(this.neurolink);
73
+ if (this.explorer && this.config.ai.explore.enabled) {
74
+ await this.explorer.initialize("local");
75
+ }
63
76
  this.localGitMcpInitialized = true;
64
77
  }
65
78
  // Step 5: Mode-specific validation
@@ -81,8 +94,9 @@ export class YamaOrchestrator {
81
94
  const sessionId = this.sessionManager.createSession(request);
82
95
  this.logReviewStart(request, sessionId);
83
96
  try {
97
+ const bootstrapStandards = await this.getBootstrappedStandards(request, sessionId);
84
98
  // Build comprehensive AI instructions
85
- const instructions = await this.promptBuilder.buildReviewInstructions(request, this.config);
99
+ const instructions = await this.promptBuilder.buildReviewInstructions(request, this.config, bootstrapStandards);
86
100
  if (this.config.display.verboseToolCalls) {
87
101
  console.log("\n📝 AI Instructions built:");
88
102
  console.log(` Instruction length: ${instructions.length} characters\n`);
@@ -90,7 +104,7 @@ export class YamaOrchestrator {
90
104
  // Create tool context for AI
91
105
  const toolContext = this.createToolContext(sessionId, request);
92
106
  // Set tool context in NeuroLink (using type assertion as setToolContext is documented but may not be in type definitions)
93
- this.neurolink.setToolContext(toolContext);
107
+ this.setToolContext(toolContext);
94
108
  // Update session metadata
95
109
  this.sessionManager.updateMetadata(sessionId, {
96
110
  aiProvider: this.config.ai.provider,
@@ -161,19 +175,14 @@ export class YamaOrchestrator {
161
175
  try {
162
176
  const diffContext = this.localDiffSource.getDiffContext(request);
163
177
  const instructions = await this.promptBuilder.buildLocalReviewInstructions(request, this.config, diffContext);
178
+ const toolContext = this.createLocalToolContext(sessionId, pseudoRequest, diffContext);
179
+ this.setToolContext(toolContext);
164
180
  const aiResponse = await this.neurolink.generate({
165
181
  input: { text: instructions },
166
182
  provider: this.config.ai.provider,
167
183
  model: this.config.ai.model,
168
184
  temperature: this.config.ai.temperature,
169
185
  maxTokens: Math.min(this.config.ai.maxTokens, 16_000),
170
- maxSteps: 100,
171
- prepareStep: async ({ stepNumber }) => {
172
- if (stepNumber >= 5) {
173
- return { toolChoice: "none" };
174
- }
175
- return undefined;
176
- },
177
186
  timeout: this.config.ai.timeout,
178
187
  enableAnalytics: this.config.ai.enableAnalytics,
179
188
  enableEvaluation: this.config.ai.enableEvaluation,
@@ -184,7 +193,7 @@ export class YamaOrchestrator {
184
193
  ...this.getLocalToolFilteringOptions(),
185
194
  context: {
186
195
  sessionId,
187
- userId: `local-${sessionId}`,
196
+ userId: this.getUserId(pseudoRequest),
188
197
  operation: "local-review",
189
198
  metadata: {
190
199
  repoPath: diffContext.repoPath,
@@ -212,11 +221,12 @@ export class YamaOrchestrator {
212
221
  await this.ensureInitialized("pr", request.configPath);
213
222
  const sessionId = this.sessionManager.createSession(request);
214
223
  try {
224
+ const bootstrapStandards = await this.getBootstrappedStandards(request, sessionId);
215
225
  // Build instructions
216
- const instructions = await this.promptBuilder.buildReviewInstructions(request, this.config);
226
+ const instructions = await this.promptBuilder.buildReviewInstructions(request, this.config, bootstrapStandards);
217
227
  // Create tool context
218
228
  const toolContext = this.createToolContext(sessionId, request);
219
- this.neurolink.setToolContext(toolContext);
229
+ this.setToolContext(toolContext);
220
230
  // Stream AI execution
221
231
  yield {
222
232
  type: "progress",
@@ -272,15 +282,16 @@ export class YamaOrchestrator {
272
282
  // ========================================================================
273
283
  // PHASE 1: Code Review
274
284
  // ========================================================================
285
+ const bootstrapStandards = await this.getBootstrappedStandards(request, sessionId);
275
286
  // Build review instructions
276
- const reviewInstructions = await this.promptBuilder.buildReviewInstructions(request, this.config);
287
+ const reviewInstructions = await this.promptBuilder.buildReviewInstructions(request, this.config, bootstrapStandards);
277
288
  if (this.config.display.verboseToolCalls) {
278
289
  console.log("\n📝 Review instructions built:");
279
290
  console.log(` Instruction length: ${reviewInstructions.length} characters\n`);
280
291
  }
281
292
  // Create tool context
282
293
  const toolContext = this.createToolContext(sessionId, request);
283
- this.neurolink.setToolContext(toolContext);
294
+ this.setToolContext(toolContext);
284
295
  // Update session metadata
285
296
  this.sessionManager.updateMetadata(sessionId, {
286
297
  aiProvider: this.config.ai.provider,
@@ -371,7 +382,7 @@ export class YamaOrchestrator {
371
382
  console.log("\n📝 Enhancing PR description...\n");
372
383
  const instructions = await this.promptBuilder.buildDescriptionEnhancementInstructions(request, this.config);
373
384
  const toolContext = this.createToolContext(sessionId, request);
374
- this.neurolink.setToolContext(toolContext);
385
+ this.setToolContext(toolContext);
375
386
  const aiResponse = await this.neurolink.generate({
376
387
  input: { text: instructions },
377
388
  provider: this.config.ai.provider,
@@ -423,6 +434,7 @@ export class YamaOrchestrator {
423
434
  createToolContext(sessionId, request) {
424
435
  return {
425
436
  sessionId,
437
+ mode: "pr",
426
438
  workspace: request.workspace,
427
439
  repository: request.repository,
428
440
  pullRequestId: request.pullRequestId,
@@ -434,6 +446,27 @@ export class YamaOrchestrator {
434
446
  },
435
447
  };
436
448
  }
449
+ createLocalToolContext(sessionId, request, diffContext) {
450
+ return {
451
+ sessionId,
452
+ mode: "local",
453
+ workspace: request.workspace,
454
+ repository: request.repository,
455
+ dryRun: request.dryRun || false,
456
+ metadata: {
457
+ yamaVersion: "2.2.1",
458
+ startTime: new Date().toISOString(),
459
+ repoPath: diffContext.repoPath,
460
+ diffSource: diffContext.diffSource,
461
+ baseRef: diffContext.baseRef,
462
+ headRef: diffContext.headRef,
463
+ },
464
+ };
465
+ }
466
+ setToolContext(context) {
467
+ this.currentToolContext = context;
468
+ this.neurolink.setToolContext(context);
469
+ }
437
470
  /**
438
471
  * Parse AI response into structured review result
439
472
  */
@@ -946,6 +979,139 @@ export class YamaOrchestrator {
946
979
  throw new Error(`NeuroLink initialization failed: ${error}`);
947
980
  }
948
981
  }
982
+ registerExploreTool() {
983
+ if (this.exploreToolRegistered || !this.config.ai.explore.enabled) {
984
+ return;
985
+ }
986
+ this.neurolink.registerTool("explore_context", {
987
+ name: "explore_context",
988
+ description: "Delegate non-trivial research to an isolated Explore worker. Use it for function definitions, project-wide search, logic tracing, commit history, rules/context lookup, or any analysis that would otherwise require broad manual scanning.",
989
+ inputSchema: {
990
+ type: "object",
991
+ properties: {
992
+ task: {
993
+ type: "string",
994
+ description: "The exact research task for Explore to investigate and answer.",
995
+ },
996
+ focus: {
997
+ type: "array",
998
+ description: "Optional list of files, symbols, commits, tickets, or context areas Explore should prioritize.",
999
+ items: {
1000
+ type: "string",
1001
+ },
1002
+ },
1003
+ },
1004
+ required: ["task"],
1005
+ },
1006
+ execute: async (params, context) => {
1007
+ if (!this.explorer) {
1008
+ throw new Error("Explore service is not initialized");
1009
+ }
1010
+ const rawParams = (params || {});
1011
+ const mergedContext = {
1012
+ ...(this.currentToolContext || {}),
1013
+ ...(context && typeof context === "object"
1014
+ ? context
1015
+ : {}),
1016
+ };
1017
+ const runtimeMode = mergedContext.mode === "local" ? "local" : "pr";
1018
+ const runtimeContext = {
1019
+ sessionId: String(mergedContext.sessionId || this.currentToolContext?.sessionId || ""),
1020
+ mode: runtimeMode,
1021
+ workspace: String(mergedContext.workspace || "local"),
1022
+ repository: String(mergedContext.repository || "repository"),
1023
+ pullRequestId: typeof mergedContext.pullRequestId === "number"
1024
+ ? mergedContext.pullRequestId
1025
+ : undefined,
1026
+ branch: typeof mergedContext.branch === "string"
1027
+ ? mergedContext.branch
1028
+ : undefined,
1029
+ dryRun: typeof mergedContext.dryRun === "boolean"
1030
+ ? mergedContext.dryRun
1031
+ : false,
1032
+ metadata: mergedContext.metadata &&
1033
+ typeof mergedContext.metadata === "object" &&
1034
+ !Array.isArray(mergedContext.metadata)
1035
+ ? mergedContext.metadata
1036
+ : {},
1037
+ };
1038
+ const focus = Array.isArray(rawParams.focus)
1039
+ ? rawParams.focus.filter((value) => typeof value === "string")
1040
+ : undefined;
1041
+ const { result, cached } = await this.explorer.explore({
1042
+ task: String(rawParams.task || "").trim(),
1043
+ focus,
1044
+ }, runtimeContext);
1045
+ return {
1046
+ success: true,
1047
+ data: {
1048
+ ...result,
1049
+ cached,
1050
+ },
1051
+ };
1052
+ },
1053
+ });
1054
+ this.exploreToolRegistered = true;
1055
+ }
1056
+ /**
1057
+ * Bootstrap repo-level standards by delegating to explore_context.
1058
+ * Runs once per (workspace/repository) per process lifetime.
1059
+ * Output is injected into the review prompt as <bootstrapped-standards>.
1060
+ * Graceful: any failure returns empty and the review proceeds without it.
1061
+ */
1062
+ async getBootstrappedStandards(request, sessionId) {
1063
+ if (!this.config.ai.explore.enabled || !this.explorer) {
1064
+ return "";
1065
+ }
1066
+ const cacheKey = `${request.workspace}/${request.repository}`.toLowerCase();
1067
+ const cached = this.bootstrapStandardsCache.get(cacheKey);
1068
+ if (cached !== undefined) {
1069
+ return cached;
1070
+ }
1071
+ const task = `Bootstrap repo review standards for ${request.workspace}/${request.repository}. Inspect the last 15 merged pull requests on this repository. For each, collect inline and summary comments left by HUMAN reviewers (ignore bot authors like "Yama", "yama-bot", "yama-review", "euler.bot"). Focus on comments that asked for code changes, flagged bugs, pushed back on an approach, or cited a convention. Distill the recurring patterns and anti-patterns the human reviewers care about — especially things that a static config rule set would miss (naming, error-handling idioms, module boundaries, test expectations, migration rules, review etiquette). Return a concise bullet list of 10-20 patterns. Each bullet: one sentence stating the pattern, optionally one sentence of rationale. Do NOT include PR numbers, author names, or raw quotes — just distilled patterns.`;
1072
+ try {
1073
+ console.log(` 🧭 Bootstrapping repo standards from recent PRs (one-time per process)...`);
1074
+ const { result } = await this.explorer.explore({ task, focus: [request.repository] }, {
1075
+ sessionId,
1076
+ mode: "pr",
1077
+ workspace: request.workspace,
1078
+ repository: request.repository,
1079
+ pullRequestId: request.pullRequestId,
1080
+ branch: request.branch,
1081
+ dryRun: request.dryRun || false,
1082
+ metadata: { bootstrap: true },
1083
+ });
1084
+ const parts = [];
1085
+ if (result.summary && result.summary.trim().length > 0) {
1086
+ parts.push(result.summary.trim());
1087
+ }
1088
+ if (result.findings && result.findings.length > 0) {
1089
+ const bullets = result.findings.map((f) => `- ${f.claim}`).join("\n");
1090
+ parts.push(bullets);
1091
+ }
1092
+ const combined = parts.join("\n\n").trim();
1093
+ if (combined.length > 0) {
1094
+ console.log(` ✅ Bootstrap standards ready (${combined.length} chars)`);
1095
+ if (this.config.display.verboseToolCalls) {
1096
+ console.log(" ───────── bootstrapped-standards ─────────");
1097
+ for (const line of combined.split("\n")) {
1098
+ console.log(` ${line}`);
1099
+ }
1100
+ console.log(" ──────────────────────────────────────────");
1101
+ }
1102
+ }
1103
+ else {
1104
+ console.log(` ⚠️ Bootstrap returned no standards — proceeding without them`);
1105
+ }
1106
+ this.bootstrapStandardsCache.set(cacheKey, combined);
1107
+ return combined;
1108
+ }
1109
+ catch (error) {
1110
+ console.warn(` ⚠️ Bootstrap standards failed, proceeding without: ${error.message}`);
1111
+ this.bootstrapStandardsCache.set(cacheKey, "");
1112
+ return "";
1113
+ }
1114
+ }
949
1115
  /**
950
1116
  * Ensure orchestrator is initialized
951
1117
  */
@@ -0,0 +1,39 @@
1
+ import { YamaConfig } from "../types/config.types.js";
2
+ import { SessionManager } from "../core/SessionManager.js";
3
+ import { MemoryManager } from "../memory/MemoryManager.js";
4
+ import { ExploreContextInput, ExploreExecutionResult, ExploreRuntimeContext } from "./types.js";
5
+ export declare class ContextExplorerService {
6
+ private readonly config;
7
+ private readonly sessionManager;
8
+ private readonly memoryManager;
9
+ private readonly projectRoot;
10
+ private readonly promptBuilder;
11
+ private readonly rulesContextLoader;
12
+ private readonly mcpManager;
13
+ private neurolink;
14
+ private prMcpInitialized;
15
+ private localMcpInitialized;
16
+ constructor(config: YamaConfig, sessionManager: SessionManager, memoryManager: MemoryManager | null, projectRoot?: string);
17
+ initialize(mode: "pr" | "local"): Promise<void>;
18
+ explore(input: ExploreContextInput, runtimeContext: ExploreRuntimeContext): Promise<ExploreExecutionResult>;
19
+ private normalizeInput;
20
+ private buildCacheKey;
21
+ private getToolFilteringOptions;
22
+ private shouldExcludeTool;
23
+ private normalizeToolName;
24
+ private normalizeResult;
25
+ private buildExtractionPrompt;
26
+ private truncateForExtraction;
27
+ private shouldCacheResult;
28
+ private normalizeFindings;
29
+ private normalizeEvidence;
30
+ private normalizeConfidence;
31
+ private normalizeSourceType;
32
+ private normalizeNextStep;
33
+ private extractJsonPayload;
34
+ private loadProjectStandards;
35
+ private loadKnowledgeBase;
36
+ private loadRepositoryMemory;
37
+ private initializeNeurolink;
38
+ }
39
+ //# sourceMappingURL=ContextExplorerService.d.ts.map