@juspay/yama 2.0.0 → 2.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.
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Langfuse Prompt Manager
3
+ * Fetches prompts from Langfuse Prompt Management with local fallbacks
4
+ *
5
+ * Prompt Names in Langfuse:
6
+ * - yama-review: Review system prompt
7
+ * - yama-enhancement: Enhancement system prompt
8
+ */
9
+ import { Langfuse } from "langfuse";
10
+ import { REVIEW_SYSTEM_PROMPT } from "./ReviewSystemPrompt.js";
11
+ import { ENHANCEMENT_SYSTEM_PROMPT } from "./EnhancementSystemPrompt.js";
12
+ import { LEARNING_EXTRACTION_PROMPT, LEARNING_SUMMARIZATION_PROMPT, } from "./LearningSystemPrompt.js";
13
+ export class LangfusePromptManager {
14
+ client = null;
15
+ initialized = false;
16
+ constructor() {
17
+ this.initializeClient();
18
+ }
19
+ /**
20
+ * Initialize Langfuse client if credentials are available
21
+ */
22
+ initializeClient() {
23
+ const publicKey = process.env.LANGFUSE_PUBLIC_KEY;
24
+ const secretKey = process.env.LANGFUSE_SECRET_KEY;
25
+ const baseUrl = process.env.LANGFUSE_BASE_URL;
26
+ if (publicKey && secretKey) {
27
+ try {
28
+ this.client = new Langfuse({
29
+ publicKey,
30
+ secretKey,
31
+ baseUrl: baseUrl || "https://cloud.langfuse.com",
32
+ });
33
+ this.initialized = true;
34
+ console.log(" 📝 Langfuse prompt management enabled");
35
+ }
36
+ catch (error) {
37
+ console.warn(" ⚠️ Failed to initialize Langfuse client:", error instanceof Error ? error.message : String(error));
38
+ this.client = null;
39
+ this.initialized = false;
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Get the review system prompt
45
+ * Fetches from Langfuse if available, otherwise returns local fallback
46
+ */
47
+ async getReviewPrompt() {
48
+ if (!this.client) {
49
+ return REVIEW_SYSTEM_PROMPT;
50
+ }
51
+ try {
52
+ const prompt = await this.client.getPrompt("yama-review", undefined, {
53
+ type: "text",
54
+ fallback: REVIEW_SYSTEM_PROMPT,
55
+ });
56
+ console.log(" ✅ Fetched review prompt from Langfuse");
57
+ return prompt.prompt;
58
+ }
59
+ catch (error) {
60
+ console.warn(" ⚠️ Failed to fetch review prompt from Langfuse, using fallback:", error instanceof Error ? error.message : String(error));
61
+ return REVIEW_SYSTEM_PROMPT;
62
+ }
63
+ }
64
+ /**
65
+ * Get the enhancement system prompt
66
+ * Fetches from Langfuse if available, otherwise returns local fallback
67
+ */
68
+ async getEnhancementPrompt() {
69
+ if (!this.client) {
70
+ return ENHANCEMENT_SYSTEM_PROMPT;
71
+ }
72
+ try {
73
+ const prompt = await this.client.getPrompt("yama-enhancement", undefined, {
74
+ type: "text",
75
+ fallback: ENHANCEMENT_SYSTEM_PROMPT,
76
+ });
77
+ console.log(" ✅ Fetched enhancement prompt from Langfuse");
78
+ return prompt.prompt;
79
+ }
80
+ catch (error) {
81
+ console.warn(" ⚠️ Failed to fetch enhancement prompt from Langfuse, using fallback:", error instanceof Error ? error.message : String(error));
82
+ return ENHANCEMENT_SYSTEM_PROMPT;
83
+ }
84
+ }
85
+ /**
86
+ * Get the learning extraction prompt
87
+ * Fetches from Langfuse if available, otherwise returns local fallback
88
+ * Langfuse prompt name: "yama-learning"
89
+ */
90
+ async getLearningPrompt() {
91
+ if (!this.client) {
92
+ return LEARNING_EXTRACTION_PROMPT;
93
+ }
94
+ try {
95
+ const prompt = await this.client.getPrompt("yama-learning", undefined, {
96
+ type: "text",
97
+ fallback: LEARNING_EXTRACTION_PROMPT,
98
+ });
99
+ console.log(" ✅ Fetched learning prompt from Langfuse");
100
+ return prompt.prompt;
101
+ }
102
+ catch (error) {
103
+ console.warn(" ⚠️ Failed to fetch learning prompt from Langfuse, using fallback:", error instanceof Error ? error.message : String(error));
104
+ return LEARNING_EXTRACTION_PROMPT;
105
+ }
106
+ }
107
+ /**
108
+ * Get the summarization prompt
109
+ * Fetches from Langfuse if available, otherwise returns local fallback
110
+ * Langfuse prompt name: "yama-summarization"
111
+ */
112
+ async getSummarizationPrompt() {
113
+ if (!this.client) {
114
+ return LEARNING_SUMMARIZATION_PROMPT;
115
+ }
116
+ try {
117
+ const prompt = await this.client.getPrompt("yama-summarization", undefined, {
118
+ type: "text",
119
+ fallback: LEARNING_SUMMARIZATION_PROMPT,
120
+ });
121
+ console.log(" ✅ Fetched summarization prompt from Langfuse");
122
+ return prompt.prompt;
123
+ }
124
+ catch (error) {
125
+ console.warn(" ⚠️ Failed to fetch summarization prompt from Langfuse, using fallback:", error instanceof Error ? error.message : String(error));
126
+ return LEARNING_SUMMARIZATION_PROMPT;
127
+ }
128
+ }
129
+ /**
130
+ * Check if Langfuse is enabled
131
+ */
132
+ isEnabled() {
133
+ return this.initialized;
134
+ }
135
+ /**
136
+ * Shutdown Langfuse client gracefully
137
+ */
138
+ async shutdown() {
139
+ if (this.client) {
140
+ await this.client.shutdownAsync();
141
+ }
142
+ }
143
+ }
144
+ //# sourceMappingURL=LangfusePromptManager.js.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Learning System Prompt
3
+ * Local fallback prompt for knowledge extraction from PR feedback
4
+ * Primary source: Langfuse (yama-learning)
5
+ */
6
+ export declare const LEARNING_EXTRACTION_PROMPT = "\n<yama-learning-system>\n <role>Knowledge Extraction Analyst</role>\n <task>Extract project-level learnings from developer feedback on AI code reviews</task>\n\n <critical-principle>\n Your goal is to extract GENERIC, PROJECT-LEVEL knowledge.\n Remove PR-specific details. Create actionable guidelines.\n Ask: \"What should AI know for ALL future reviews of this project?\"\n </critical-principle>\n\n <instructions>\n For each AI comment + developer response pair provided:\n 1. Understand what the developer is teaching\n 2. Abstract into a project-level guideline\n 3. Categorize appropriately\n 4. Identify file patterns where this applies (if relevant)\n 5. Do NOT include PR-specific references (PR numbers, dates, developer names)\n </instructions>\n\n <categories>\n <category name=\"false_positive\">\n Things AI incorrectly flagged that should NOT be flagged.\n Use when developer says: \"this is intentional\", \"not an issue\", \"by design\", \"we prefer this\"\n Example: \"Promise.all() for parallel async is acceptable when awaited\"\n </category>\n\n <category name=\"missed_issue\">\n Things developer pointed out that AI should have caught.\n Use when developer says: \"you missed\", \"also check\", \"what about\"\n Example: \"Always validate JWT audience in multi-tenant endpoints\"\n </category>\n\n <category name=\"style_preference\">\n Team conventions that differ from general best practices.\n Use when developer says: \"we prefer\", \"our convention\", \"team decision\"\n Example: \"Use type over interface for all type definitions\"\n </category>\n\n <category name=\"domain_context\">\n Project-specific architecture or context AI needs.\n Use when developer explains project structure, dependencies, or patterns.\n Example: \"src/services/ contains business logic, handlers are thin wrappers\"\n </category>\n\n <category name=\"enhancement_guideline\">\n How AI should approach suggestions for this project.\n Use when developer guides on comment style, severity, or scope.\n Example: \"Don't suggest JSDoc for internal functions\"\n </category>\n </categories>\n\n <output-format>\n Return a JSON array of learnings. Each learning should be:\n - Actionable and specific\n - Generic (applicable to future reviews)\n - Free of PR-specific details\n\n Format:\n [\n {\n \"category\": \"false_positive\",\n \"subcategory\": \"Async Patterns\",\n \"learning\": \"Clear, actionable guideline for future reviews...\",\n \"filePatterns\": [\"**/services/**/*.ts\"],\n \"reasoning\": \"Brief explanation of why this matters\"\n }\n ]\n\n Return an EMPTY array [] if no actionable learnings can be extracted.\n </output-format>\n\n <examples>\n <example>\n <ai-comment>\n \uD83D\uDD12 SECURITY: This Promise.all() could cause memory issues if the array is large.\n Consider using batching.\n </ai-comment>\n <developer-reply>\n This is intentional - we want parallel execution here for performance.\n The array is always small (< 10 items) from our API pagination.\n </developer-reply>\n <extracted-learning>\n {\n \"category\": \"false_positive\",\n \"subcategory\": \"Async Patterns\",\n \"learning\": \"Promise.all() for parallel async operations is acceptable when the collection size is bounded and known to be small\",\n \"filePatterns\": null,\n \"reasoning\": \"Team uses Promise.all() intentionally for performance with small, bounded collections\"\n }\n </extracted-learning>\n </example>\n\n <example>\n <ai-comment>\n \u26A0\uFE0F MAJOR: Consider adding input validation for this API endpoint.\n </ai-comment>\n <developer-reply>\n Good point, but you missed that we also need to sanitize the input\n before logging - we had a PII exposure issue before.\n </developer-reply>\n <extracted-learning>\n {\n \"category\": \"missed_issue\",\n \"subcategory\": \"Security\",\n \"learning\": \"Sanitize user input before logging to prevent PII exposure\",\n \"filePatterns\": [\"**/api/**\", \"**/handlers/**\"],\n \"reasoning\": \"Historical PII exposure issue - logging must use sanitized values\"\n }\n </extracted-learning>\n </example>\n\n <example>\n <ai-comment>\n \uD83D\uDCA1 MINOR: Consider using 'interface' instead of 'type' for object shapes.\n </ai-comment>\n <developer-reply>\n We prefer 'type' for everything in this project - team decision.\n </developer-reply>\n <extracted-learning>\n {\n \"category\": \"style_preference\",\n \"subcategory\": \"TypeScript\",\n \"learning\": \"Use 'type' over 'interface' for all type definitions\",\n \"filePatterns\": [\"**/*.ts\", \"**/*.tsx\"],\n \"reasoning\": \"Team convention to use type aliases consistently\"\n }\n </extracted-learning>\n </example>\n </examples>\n</yama-learning-system>\n";
7
+ /**
8
+ * Summarization prompt for consolidating knowledge base entries
9
+ */
10
+ export declare const LEARNING_SUMMARIZATION_PROMPT = "\n<yama-summarization-task>\n <goal>Consolidate knowledge base learnings into concise, actionable guidelines</goal>\n\n <instructions>\n You will receive the current knowledge base content.\n For each category section:\n 1. Identify duplicate or highly similar learnings\n 2. Merge related learnings into single statements\n 3. Keep the most general, actionable form\n 4. Preserve file patterns where applicable\n 5. Ensure no information is lost, just condensed\n </instructions>\n\n <rules>\n - Combine learnings that say the same thing differently\n - Keep specific technical details (don't over-generalize)\n - Preserve all unique learnings\n - Maintain subcategory organization\n - Update the total count accurately\n </rules>\n\n <example>\n Before:\n - Don't flag Promise.all() in services\n - Promise.all() is acceptable in async handlers\n - Parallel Promise execution is intentional\n\n After:\n - Promise.all() for parallel async operations is acceptable across the codebase\n </example>\n\n <output-format>\n Return the complete, updated knowledge base in markdown format.\n Preserve the exact structure (headers, sections, metadata).\n Update the metadata with new total count and summarization timestamp.\n </output-format>\n</yama-summarization-task>\n";
11
+ //# sourceMappingURL=LearningSystemPrompt.d.ts.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Learning System Prompt
3
+ * Local fallback prompt for knowledge extraction from PR feedback
4
+ * Primary source: Langfuse (yama-learning)
5
+ */
6
+ export const LEARNING_EXTRACTION_PROMPT = `
7
+ <yama-learning-system>
8
+ <role>Knowledge Extraction Analyst</role>
9
+ <task>Extract project-level learnings from developer feedback on AI code reviews</task>
10
+
11
+ <critical-principle>
12
+ Your goal is to extract GENERIC, PROJECT-LEVEL knowledge.
13
+ Remove PR-specific details. Create actionable guidelines.
14
+ Ask: "What should AI know for ALL future reviews of this project?"
15
+ </critical-principle>
16
+
17
+ <instructions>
18
+ For each AI comment + developer response pair provided:
19
+ 1. Understand what the developer is teaching
20
+ 2. Abstract into a project-level guideline
21
+ 3. Categorize appropriately
22
+ 4. Identify file patterns where this applies (if relevant)
23
+ 5. Do NOT include PR-specific references (PR numbers, dates, developer names)
24
+ </instructions>
25
+
26
+ <categories>
27
+ <category name="false_positive">
28
+ Things AI incorrectly flagged that should NOT be flagged.
29
+ Use when developer says: "this is intentional", "not an issue", "by design", "we prefer this"
30
+ Example: "Promise.all() for parallel async is acceptable when awaited"
31
+ </category>
32
+
33
+ <category name="missed_issue">
34
+ Things developer pointed out that AI should have caught.
35
+ Use when developer says: "you missed", "also check", "what about"
36
+ Example: "Always validate JWT audience in multi-tenant endpoints"
37
+ </category>
38
+
39
+ <category name="style_preference">
40
+ Team conventions that differ from general best practices.
41
+ Use when developer says: "we prefer", "our convention", "team decision"
42
+ Example: "Use type over interface for all type definitions"
43
+ </category>
44
+
45
+ <category name="domain_context">
46
+ Project-specific architecture or context AI needs.
47
+ Use when developer explains project structure, dependencies, or patterns.
48
+ Example: "src/services/ contains business logic, handlers are thin wrappers"
49
+ </category>
50
+
51
+ <category name="enhancement_guideline">
52
+ How AI should approach suggestions for this project.
53
+ Use when developer guides on comment style, severity, or scope.
54
+ Example: "Don't suggest JSDoc for internal functions"
55
+ </category>
56
+ </categories>
57
+
58
+ <output-format>
59
+ Return a JSON array of learnings. Each learning should be:
60
+ - Actionable and specific
61
+ - Generic (applicable to future reviews)
62
+ - Free of PR-specific details
63
+
64
+ Format:
65
+ [
66
+ {
67
+ "category": "false_positive",
68
+ "subcategory": "Async Patterns",
69
+ "learning": "Clear, actionable guideline for future reviews...",
70
+ "filePatterns": ["**/services/**/*.ts"],
71
+ "reasoning": "Brief explanation of why this matters"
72
+ }
73
+ ]
74
+
75
+ Return an EMPTY array [] if no actionable learnings can be extracted.
76
+ </output-format>
77
+
78
+ <examples>
79
+ <example>
80
+ <ai-comment>
81
+ 🔒 SECURITY: This Promise.all() could cause memory issues if the array is large.
82
+ Consider using batching.
83
+ </ai-comment>
84
+ <developer-reply>
85
+ This is intentional - we want parallel execution here for performance.
86
+ The array is always small (< 10 items) from our API pagination.
87
+ </developer-reply>
88
+ <extracted-learning>
89
+ {
90
+ "category": "false_positive",
91
+ "subcategory": "Async Patterns",
92
+ "learning": "Promise.all() for parallel async operations is acceptable when the collection size is bounded and known to be small",
93
+ "filePatterns": null,
94
+ "reasoning": "Team uses Promise.all() intentionally for performance with small, bounded collections"
95
+ }
96
+ </extracted-learning>
97
+ </example>
98
+
99
+ <example>
100
+ <ai-comment>
101
+ ⚠️ MAJOR: Consider adding input validation for this API endpoint.
102
+ </ai-comment>
103
+ <developer-reply>
104
+ Good point, but you missed that we also need to sanitize the input
105
+ before logging - we had a PII exposure issue before.
106
+ </developer-reply>
107
+ <extracted-learning>
108
+ {
109
+ "category": "missed_issue",
110
+ "subcategory": "Security",
111
+ "learning": "Sanitize user input before logging to prevent PII exposure",
112
+ "filePatterns": ["**/api/**", "**/handlers/**"],
113
+ "reasoning": "Historical PII exposure issue - logging must use sanitized values"
114
+ }
115
+ </extracted-learning>
116
+ </example>
117
+
118
+ <example>
119
+ <ai-comment>
120
+ 💡 MINOR: Consider using 'interface' instead of 'type' for object shapes.
121
+ </ai-comment>
122
+ <developer-reply>
123
+ We prefer 'type' for everything in this project - team decision.
124
+ </developer-reply>
125
+ <extracted-learning>
126
+ {
127
+ "category": "style_preference",
128
+ "subcategory": "TypeScript",
129
+ "learning": "Use 'type' over 'interface' for all type definitions",
130
+ "filePatterns": ["**/*.ts", "**/*.tsx"],
131
+ "reasoning": "Team convention to use type aliases consistently"
132
+ }
133
+ </extracted-learning>
134
+ </example>
135
+ </examples>
136
+ </yama-learning-system>
137
+ `;
138
+ /**
139
+ * Summarization prompt for consolidating knowledge base entries
140
+ */
141
+ export const LEARNING_SUMMARIZATION_PROMPT = `
142
+ <yama-summarization-task>
143
+ <goal>Consolidate knowledge base learnings into concise, actionable guidelines</goal>
144
+
145
+ <instructions>
146
+ You will receive the current knowledge base content.
147
+ For each category section:
148
+ 1. Identify duplicate or highly similar learnings
149
+ 2. Merge related learnings into single statements
150
+ 3. Keep the most general, actionable form
151
+ 4. Preserve file patterns where applicable
152
+ 5. Ensure no information is lost, just condensed
153
+ </instructions>
154
+
155
+ <rules>
156
+ - Combine learnings that say the same thing differently
157
+ - Keep specific technical details (don't over-generalize)
158
+ - Preserve all unique learnings
159
+ - Maintain subcategory organization
160
+ - Update the total count accurately
161
+ </rules>
162
+
163
+ <example>
164
+ Before:
165
+ - Don't flag Promise.all() in services
166
+ - Promise.all() is acceptable in async handlers
167
+ - Parallel Promise execution is intentional
168
+
169
+ After:
170
+ - Promise.all() for parallel async operations is acceptable across the codebase
171
+ </example>
172
+
173
+ <output-format>
174
+ Return the complete, updated knowledge base in markdown format.
175
+ Preserve the exact structure (headers, sections, metadata).
176
+ Update the metadata with new total count and summarization timestamp.
177
+ </output-format>
178
+ </yama-summarization-task>
179
+ `;
180
+ //# sourceMappingURL=LearningSystemPrompt.js.map
@@ -8,6 +8,8 @@
8
8
  import { YamaV2Config } from "../types/config.types.js";
9
9
  import { ReviewRequest } from "../types/v2.types.js";
10
10
  export declare class PromptBuilder {
11
+ private langfuseManager;
12
+ constructor();
11
13
  /**
12
14
  * Build complete review instructions for AI
13
15
  * Combines generic base prompt + project-specific config
@@ -26,6 +28,11 @@ export declare class PromptBuilder {
26
28
  * Load project-specific standards from repository
27
29
  */
28
30
  private loadProjectStandards;
31
+ /**
32
+ * Load knowledge base for AI prompt injection
33
+ * Contains learned patterns from previous PR feedback
34
+ */
35
+ private loadKnowledgeBase;
29
36
  /**
30
37
  * Build description enhancement prompt separately (for description-only operations)
31
38
  */
@@ -8,20 +8,26 @@
8
8
  import { readFile } from "fs/promises";
9
9
  import { existsSync } from "fs";
10
10
  import { join } from "path";
11
- import { REVIEW_SYSTEM_PROMPT } from "./ReviewSystemPrompt.js";
12
- import { ENHANCEMENT_SYSTEM_PROMPT } from "./EnhancementSystemPrompt.js";
11
+ import { LangfusePromptManager } from "./LangfusePromptManager.js";
12
+ import { KnowledgeBaseManager } from "../learning/KnowledgeBaseManager.js";
13
13
  export class PromptBuilder {
14
+ langfuseManager;
15
+ constructor() {
16
+ this.langfuseManager = new LangfusePromptManager();
17
+ }
14
18
  /**
15
19
  * Build complete review instructions for AI
16
20
  * Combines generic base prompt + project-specific config
17
21
  */
18
22
  async buildReviewInstructions(request, config) {
19
- // Base system prompt (generic, project-agnostic)
20
- const basePrompt = REVIEW_SYSTEM_PROMPT;
23
+ // Base system prompt - fetched from Langfuse or local fallback
24
+ const basePrompt = await this.langfuseManager.getReviewPrompt();
21
25
  // Project-specific configuration in XML format
22
26
  const projectConfig = this.buildProjectConfigXML(config, request);
23
27
  // Project-specific standards (if available)
24
28
  const projectStandards = await this.loadProjectStandards(config);
29
+ // Knowledge base learnings (reinforcement learning)
30
+ const knowledgeBase = await this.loadKnowledgeBase(config);
25
31
  // Combine all parts
26
32
  return `
27
33
  ${basePrompt}
@@ -32,6 +38,8 @@ ${projectConfig}
32
38
 
33
39
  ${projectStandards ? `<project-standards>\n${projectStandards}\n</project-standards>` : ""}
34
40
 
41
+ ${knowledgeBase ? `<learned-knowledge>\n${knowledgeBase}\n</learned-knowledge>` : ""}
42
+
35
43
  <review-task>
36
44
  <workspace>${this.escapeXML(request.workspace)}</workspace>
37
45
  <repository>${this.escapeXML(request.repository)}</repository>
@@ -67,7 +75,7 @@ ${projectStandards ? `<project-standards>\n${projectStandards}\n</project-standa
67
75
  <description>${this.escapeXML(area.description)}</description>
68
76
  </focus-area>`)
69
77
  .join("\n");
70
- const blockingCriteriaXML = config.review.blockingCriteria
78
+ const blockingCriteriaXML = (config.review.blockingCriteria || [])
71
79
  .map((criteria) => `
72
80
  <criterion>
73
81
  <condition>${this.escapeXML(criteria.condition)}</condition>
@@ -157,12 +165,33 @@ Follow these in addition to the general focus areas:
157
165
  ${loadedStandards.join("\n\n---\n\n")}
158
166
  `.trim();
159
167
  }
168
+ /**
169
+ * Load knowledge base for AI prompt injection
170
+ * Contains learned patterns from previous PR feedback
171
+ */
172
+ async loadKnowledgeBase(config) {
173
+ if (!config.knowledgeBase?.enabled) {
174
+ return null;
175
+ }
176
+ try {
177
+ const kbManager = new KnowledgeBaseManager(config.knowledgeBase);
178
+ const content = await kbManager.getForPrompt();
179
+ if (content) {
180
+ console.log(" 📚 Knowledge base loaded for AI context");
181
+ }
182
+ return content;
183
+ }
184
+ catch (error) {
185
+ // Silently fail - knowledge base is optional enhancement
186
+ return null;
187
+ }
188
+ }
160
189
  /**
161
190
  * Build description enhancement prompt separately (for description-only operations)
162
191
  */
163
192
  async buildDescriptionEnhancementInstructions(request, config) {
164
- // Base enhancement prompt (generic, project-agnostic)
165
- const basePrompt = ENHANCEMENT_SYSTEM_PROMPT;
193
+ // Base enhancement prompt - fetched from Langfuse or local fallback
194
+ const basePrompt = await this.langfuseManager.getEnhancementPrompt();
166
195
  // Project-specific enhancement configuration
167
196
  const enhancementConfigXML = this.buildEnhancementConfigXML(config);
168
197
  return `
@@ -11,6 +11,7 @@ export interface YamaV2Config {
11
11
  review: ReviewConfig;
12
12
  descriptionEnhancement: DescriptionEnhancementConfig;
13
13
  memoryBank: MemoryBankConfig;
14
+ knowledgeBase: KnowledgeBaseConfig;
14
15
  projectStandards?: ProjectStandardsConfig;
15
16
  monitoring: MonitoringConfig;
16
17
  performance: PerformanceConfig;
@@ -48,15 +49,21 @@ export interface RedisConfig {
48
49
  ttl?: number;
49
50
  }
50
51
  export interface MCPServersConfig {
52
+ bitbucket?: {
53
+ /** List of tool names to block from Bitbucket MCP server */
54
+ blockedTools?: string[];
55
+ };
51
56
  jira: {
52
57
  enabled: boolean;
58
+ /** List of tool names to block from Jira MCP server */
59
+ blockedTools?: string[];
53
60
  };
54
61
  }
55
62
  export interface ReviewConfig {
56
63
  enabled: boolean;
57
64
  workflowInstructions: string;
58
65
  focusAreas: FocusArea[];
59
- blockingCriteria: BlockingCriteria[];
66
+ blockingCriteria?: BlockingCriteria[];
60
67
  excludePatterns: string[];
61
68
  contextLines: number;
62
69
  maxFilesPerReview: number;
@@ -90,6 +97,20 @@ export interface MemoryBankConfig {
90
97
  fallbackPaths: string[];
91
98
  standardFiles?: string[];
92
99
  }
100
+ export interface KnowledgeBaseConfig {
101
+ /** Enable knowledge base feature */
102
+ enabled: boolean;
103
+ /** Path to knowledge base file (relative to project root) */
104
+ path: string;
105
+ /** Patterns to identify AI comment authors (case-insensitive) */
106
+ aiAuthorPatterns: string[];
107
+ /** Number of learnings before auto-summarization triggers */
108
+ maxEntriesBeforeSummarization: number;
109
+ /** Number of entries to retain after summarization */
110
+ summaryRetentionCount: number;
111
+ /** Auto-commit knowledge base changes (default for --commit flag) */
112
+ autoCommit: boolean;
113
+ }
93
114
  export interface ProjectStandardsConfig {
94
115
  customPromptsPath: string;
95
116
  additionalFocusAreas: FocusArea[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/yama",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Enterprise-grade Pull Request automation toolkit with AI-powered code review and description enhancement",
5
5
  "keywords": [
6
6
  "pr",
@@ -83,7 +83,8 @@
83
83
  "check:all": "npm run lint && npm run format --check && npm run validate && npm run validate:commit"
84
84
  },
85
85
  "dependencies": {
86
- "@juspay/neurolink": "^8.1.0",
86
+ "@juspay/neurolink": "^8.23.1",
87
+ "langfuse": "^3.35.0",
87
88
  "@nexus2520/bitbucket-mcp-server": "^1.1.2",
88
89
  "@nexus2520/jira-mcp-server": "^1.0.1",
89
90
  "chalk": "^4.1.2",
@@ -150,7 +151,10 @@
150
151
  "pnpm": {
151
152
  "onlyBuiltDependencies": [
152
153
  "esbuild"
153
- ]
154
+ ],
155
+ "overrides": {
156
+ "@semantic-release/npm": "^13.1.2"
157
+ }
154
158
  },
155
159
  "lint-staged": {
156
160
  "*.{ts,tsx,js,jsx}": [
@@ -39,9 +39,25 @@ ai:
39
39
  # ============================================================================
40
40
  # Bitbucket MCP is always enabled (hardcoded)
41
41
  # Jira MCP can be enabled/disabled here
42
+ # Use blockedTools to prevent AI from using specific MCP tools
42
43
  mcpServers:
44
+ bitbucket:
45
+ # Optional: Block specific Bitbucket tools from AI access
46
+ # This prevents the AI from performing certain actions
47
+ blockedTools: []
48
+ # Example blocked tools (uncomment to use):
49
+ # - merge_pull_request # Prevent AI from merging PRs
50
+ # - delete_branch # Prevent AI from deleting branches
51
+ # - approve_pull_request # Prevent AI from auto-approving PRs
52
+
43
53
  jira:
44
54
  enabled: true # Set to false to disable Jira integration
55
+ # Optional: Block specific Jira tools from AI access
56
+ blockedTools: []
57
+ # Example blocked tools (uncomment to use):
58
+ # - jira_create_issue # Prevent AI from creating Jira issues
59
+ # - jira_delete_issue # Prevent AI from deleting issues
60
+ # - jira_update_issue # Prevent AI from modifying issues
45
61
 
46
62
  # ============================================================================
47
63
  # Review Configuration
@@ -89,19 +105,22 @@ review:
89
105
  - Poor naming conventions
90
106
  - Missing edge case handling
91
107
 
92
- # Blocking criteria (AI uses these to decide whether to block PR)
93
- blockingCriteria:
94
- - condition: "ANY CRITICAL severity issue"
95
- action: "BLOCK"
96
- reason: "Security or data loss risk"
97
-
98
- - condition: "3 or more MAJOR severity issues"
99
- action: "BLOCK"
100
- reason: "Too many significant bugs/performance issues"
101
-
102
- - condition: "Jira requirement coverage < 70%"
103
- action: "BLOCK"
104
- reason: "Incomplete implementation of requirements"
108
+ # Blocking criteria (OPTIONAL - AI uses these to decide whether to block PR)
109
+ # If not provided or empty, AI will review and comment but NOT auto-block/approve PRs
110
+ # Uncomment and customize the examples below to enable auto-blocking:
111
+ blockingCriteria: []
112
+ # blockingCriteria:
113
+ # - condition: "ANY CRITICAL severity issue"
114
+ # action: "BLOCK"
115
+ # reason: "Security or data loss risk"
116
+ #
117
+ # - condition: "3 or more MAJOR severity issues"
118
+ # action: "BLOCK"
119
+ # reason: "Too many significant bugs/performance issues"
120
+ #
121
+ # - condition: "Jira requirement coverage < 70%"
122
+ # action: "BLOCK"
123
+ # reason: "Incomplete implementation of requirements"
105
124
 
106
125
  # Files to exclude from analysis
107
126
  excludePatterns:
@@ -183,6 +202,32 @@ memoryBank:
183
202
  - "coding-standards.md"
184
203
  - "security-guidelines.md"
185
204
 
205
+ # ============================================================================
206
+ # Knowledge Base - Reinforcement Learning from PR Feedback
207
+ # ============================================================================
208
+ # Yama learns from developer feedback on AI comments across merged PRs.
209
+ # Use 'yama learn -w <workspace> -r <repo> -p <pr-id>' to extract learnings.
210
+ knowledgeBase:
211
+ enabled: true
212
+
213
+ # Path to knowledge base file (relative to repo root)
214
+ path: ".yama/knowledge-base.md"
215
+
216
+ # Patterns to identify AI-generated comments (author name matching)
217
+ aiAuthorPatterns:
218
+ - "Yama"
219
+ - "yama-bot"
220
+ - "yama-review"
221
+
222
+ # Automatically summarize knowledge base when entry count exceeds this
223
+ maxEntriesBeforeSummarization: 50
224
+
225
+ # How many consolidated entries to keep after summarization
226
+ summaryRetentionCount: 20
227
+
228
+ # Automatically commit knowledge base changes (with --commit flag)
229
+ autoCommit: false
230
+
186
231
  # ============================================================================
187
232
  # Project-Specific Standards (Override in your repository)
188
233
  # ============================================================================