tuna-agent 0.1.132 → 0.1.133

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.
@@ -964,7 +964,7 @@ export class ClaudeCodeAdapter {
964
964
  }
965
965
  }
966
966
  // Filter 1: Quality gate — reject garbage rules
967
- const MAX_LEARNED_RULES = 20;
967
+ const MAX_LEARNED_RULES = 50;
968
968
  const MIN_CONFIDENCE = 2;
969
969
  const qualityPatterns = patterns.filter(p => {
970
970
  const r = p.rule.trim();
@@ -998,12 +998,50 @@ export class ClaudeCodeAdapter {
998
998
  }
999
999
  return true;
1000
1000
  });
1001
- // Cap total rules if already at max, skip adding more
1002
- if (existingRules.length >= MAX_LEARNED_RULES) {
1003
- console.log(`[Self-Improve] Already at max ${MAX_LEARNED_RULES} rules — skipping`);
1004
- return;
1001
+ // If at max, try rotation: replace lowest-confidence existing rules with higher-confidence new ones
1002
+ let slotsAvailable = MAX_LEARNED_RULES - existingRules.length;
1003
+ let rotatedOut = [];
1004
+ if (slotsAvailable <= 0 && qualityPatterns.length > 0) {
1005
+ // Parse existing rules with their confidence values and line text
1006
+ const existingWithConf = [];
1007
+ if (sectionIdx !== -1) {
1008
+ const sectionContent = existingContent.substring(sectionIdx + SECTION_HEADER.length);
1009
+ const nextSection = sectionContent.indexOf('\n## ');
1010
+ const rulesText = nextSection !== -1 ? sectionContent.substring(0, nextSection) : sectionContent;
1011
+ for (const line of rulesText.split('\n')) {
1012
+ const trimmed = line.trim();
1013
+ if (trimmed.startsWith('- ')) {
1014
+ const confMatch = trimmed.match(/\(confidence:\s*([\d.]+)\)\s*$/);
1015
+ const conf = confMatch ? parseFloat(confMatch[1]) : 1;
1016
+ existingWithConf.push({ text: trimmed.substring(2), confidence: conf, line: trimmed });
1017
+ }
1018
+ }
1019
+ }
1020
+ // Sort existing by confidence ascending (weakest first)
1021
+ existingWithConf.sort((a, b) => a.confidence - b.confidence);
1022
+ // Find new patterns with higher confidence than weakest existing rules
1023
+ const maxNewConfidence = Math.max(...qualityPatterns.map(p => p.confidence));
1024
+ const weakest = existingWithConf.filter(r => r.confidence < maxNewConfidence);
1025
+ if (weakest.length > 0) {
1026
+ // Rotate out up to 3 weakest rules
1027
+ rotatedOut = weakest.slice(0, 3);
1028
+ slotsAvailable = rotatedOut.length;
1029
+ // Remove rotated-out rules from existingContent
1030
+ for (const old of rotatedOut) {
1031
+ existingContent = existingContent.replace(old.line + '\n', '');
1032
+ // Also remove from existingRules for dedup check
1033
+ const ruleText = old.line.replace(/^- /, '').replace(/\s*\(confidence:\s*[\d.]+\)\s*$/, '');
1034
+ const idx = existingRules.indexOf(ruleText);
1035
+ if (idx !== -1)
1036
+ existingRules.splice(idx, 1);
1037
+ }
1038
+ console.log(`[Self-Improve] Rotation: removing ${rotatedOut.length} weak rules (confidence: ${rotatedOut.map(r => r.confidence).join(', ')})`);
1039
+ }
1040
+ else {
1041
+ console.log(`[Self-Improve] At max ${MAX_LEARNED_RULES} rules, no weaker rules to rotate out — skipping`);
1042
+ return;
1043
+ }
1005
1044
  }
1006
- const slotsAvailable = MAX_LEARNED_RULES - existingRules.length;
1007
1045
  // Filter 2: skip patterns similar to ANY existing rule
1008
1046
  const newPatterns = qualityPatterns.filter(p => {
1009
1047
  return !existingRules.some(existing => ClaudeCodeAdapter.isSimilarRule(p.rule, existing));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tuna-agent",
3
- "version": "0.1.132",
3
+ "version": "0.1.133",
4
4
  "description": "Tuna Agent - Run AI coding tasks on your machine",
5
5
  "bin": {
6
6
  "tuna-agent": "dist/cli/index.js"