a2a-memory 0.7.0 → 0.8.2
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/adapters/anthropic.d.ts.map +1 -1
- package/dist/adapters/anthropic.js +1 -0
- package/dist/adapters/anthropic.js.map +1 -1
- package/dist/claude/sync.js +6 -6
- package/dist/claude/sync.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +16 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/health.d.ts.map +1 -1
- package/dist/cli/commands/health.js +3 -6
- package/dist/cli/commands/health.js.map +1 -1
- package/dist/cli/commands/proficiency.d.ts +8 -0
- package/dist/cli/commands/proficiency.d.ts.map +1 -0
- package/dist/cli/commands/proficiency.js +142 -0
- package/dist/cli/commands/proficiency.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +8 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +136 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/commands/sync.js +16 -11
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +0 -2
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/config/manager.d.ts +682 -0
- package/dist/config/manager.d.ts.map +1 -1
- package/dist/config/manager.js +79 -4
- package/dist/config/manager.js.map +1 -1
- package/dist/db/database.d.ts +65 -0
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/database.js +276 -3
- package/dist/db/database.js.map +1 -1
- package/dist/extraction/extractor.d.ts +4 -0
- package/dist/extraction/extractor.d.ts.map +1 -1
- package/dist/extraction/extractor.js +261 -38
- package/dist/extraction/extractor.js.map +1 -1
- package/dist/extraction/scorer.js +5 -3
- package/dist/extraction/scorer.js.map +1 -1
- package/dist/hooks/post-tool-use.d.ts.map +1 -1
- package/dist/hooks/post-tool-use.js +78 -15
- package/dist/hooks/post-tool-use.js.map +1 -1
- package/dist/hooks/session-end.d.ts.map +1 -1
- package/dist/hooks/session-end.js +81 -13
- package/dist/hooks/session-end.js.map +1 -1
- package/dist/hooks/session-start.d.ts.map +1 -1
- package/dist/hooks/session-start.js +104 -36
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/cleanup.d.ts.map +1 -1
- package/dist/lifecycle/cleanup.js +2 -1
- package/dist/lifecycle/cleanup.js.map +1 -1
- package/dist/llm/client.d.ts +22 -0
- package/dist/llm/client.d.ts.map +1 -1
- package/dist/llm/client.js +74 -2
- package/dist/llm/client.js.map +1 -1
- package/dist/proficiency/actr-engine.d.ts +55 -0
- package/dist/proficiency/actr-engine.d.ts.map +1 -0
- package/dist/proficiency/actr-engine.js +106 -0
- package/dist/proficiency/actr-engine.js.map +1 -0
- package/dist/proficiency/index.d.ts +9 -0
- package/dist/proficiency/index.d.ts.map +1 -0
- package/dist/proficiency/index.js +8 -0
- package/dist/proficiency/index.js.map +1 -0
- package/dist/proficiency/tracker.d.ts +50 -0
- package/dist/proficiency/tracker.d.ts.map +1 -0
- package/dist/proficiency/tracker.js +170 -0
- package/dist/proficiency/tracker.js.map +1 -0
- package/dist/proficiency/types.d.ts +60 -0
- package/dist/proficiency/types.d.ts.map +1 -0
- package/dist/proficiency/types.js +8 -0
- package/dist/proficiency/types.js.map +1 -0
- package/dist/providers/adapters.d.ts +54 -0
- package/dist/providers/adapters.d.ts.map +1 -0
- package/dist/providers/adapters.js +140 -0
- package/dist/providers/adapters.js.map +1 -0
- package/dist/providers/detector.d.ts +17 -0
- package/dist/providers/detector.d.ts.map +1 -0
- package/dist/providers/detector.js +57 -0
- package/dist/providers/detector.js.map +1 -0
- package/dist/search/ranker.d.ts +26 -2
- package/dist/search/ranker.d.ts.map +1 -1
- package/dist/search/ranker.js +121 -46
- package/dist/search/ranker.js.map +1 -1
- package/dist/session/parser.d.ts.map +1 -1
- package/dist/session/parser.js +1 -0
- package/dist/session/parser.js.map +1 -1
- package/dist/skill/evaluator.d.ts +57 -0
- package/dist/skill/evaluator.d.ts.map +1 -0
- package/dist/skill/evaluator.js +373 -0
- package/dist/skill/evaluator.js.map +1 -0
- package/dist/skill/index.d.ts +8 -0
- package/dist/skill/index.d.ts.map +1 -0
- package/dist/skill/index.js +7 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/skill/types.d.ts +34 -0
- package/dist/skill/types.d.ts.map +1 -0
- package/dist/skill/types.js +7 -0
- package/dist/skill/types.js.map +1 -0
- package/dist/sync/client.d.ts +1 -0
- package/dist/sync/client.d.ts.map +1 -1
- package/dist/sync/client.js +1 -1
- package/dist/sync/client.js.map +1 -1
- package/dist/sync/queue.d.ts +1 -0
- package/dist/sync/queue.d.ts.map +1 -1
- package/dist/sync/queue.js +36 -7
- package/dist/sync/queue.js.map +1 -1
- package/dist/sync/synchronizer.js +1 -1
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/team-synchronizer.d.ts +6 -2
- package/dist/sync/team-synchronizer.d.ts.map +1 -1
- package/dist/sync/team-synchronizer.js +84 -6
- package/dist/sync/team-synchronizer.js.map +1 -1
- package/dist/sync/vector-clock.d.ts +7 -0
- package/dist/sync/vector-clock.d.ts.map +1 -1
- package/dist/sync/vector-clock.js +30 -0
- package/dist/sync/vector-clock.js.map +1 -1
- package/dist/types/index.d.ts +27 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +24 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/keychain.d.ts.map +1 -1
- package/dist/utils/keychain.js +4 -0
- package/dist/utils/keychain.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +12 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACT-R Activation Engine
|
|
3
|
+
*
|
|
4
|
+
* Backend src/core/actr/engine.py 의 TypeScript 포트.
|
|
5
|
+
* Power Law of Practice + Forgetting Curve 기반 활성화 계산.
|
|
6
|
+
*
|
|
7
|
+
* 공식:
|
|
8
|
+
* B_i = ln(sum(t_j^(-d))) + B // Base-level (시간 감쇠)
|
|
9
|
+
* S_i = sum(W_j * S_ji) // Spreading (컨텍스트 연관)
|
|
10
|
+
* P_i = -P * (1 - similarity) // Partial Match (유사도 보정)
|
|
11
|
+
* A_i = B_i + S_i + P_i // Total Activation
|
|
12
|
+
*/
|
|
13
|
+
const CLAMP_MIN = 1e-10;
|
|
14
|
+
const CLAMP_MAX = 1e10;
|
|
15
|
+
export class ACTREngine {
|
|
16
|
+
config;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 전체 활성화 계산
|
|
22
|
+
*
|
|
23
|
+
* @param accessTimes - 접근 시간 배열 (현재 시점에서의 경과 초, 양수)
|
|
24
|
+
* @param associations - [{ source, strength }] 연관 소스와 강도
|
|
25
|
+
* @param context - 현재 활성 컨텍스트 소스 집합
|
|
26
|
+
* @param similarity - 유사도 (0.0-1.0, 1.0=완벽 일치)
|
|
27
|
+
* @param memoryId - 식별용 ID
|
|
28
|
+
*/
|
|
29
|
+
computeActivation(accessTimes, associations, context, similarity, memoryId = '') {
|
|
30
|
+
const baseLevel = this.computeBaseLevel(accessTimes);
|
|
31
|
+
const spreading = this.computeSpreading(associations, context);
|
|
32
|
+
const partialMatch = this.computePartialMatch(similarity);
|
|
33
|
+
const total = baseLevel + spreading + partialMatch;
|
|
34
|
+
return {
|
|
35
|
+
memoryId,
|
|
36
|
+
baseLevel,
|
|
37
|
+
spreading,
|
|
38
|
+
partialMatch,
|
|
39
|
+
total,
|
|
40
|
+
shouldRetrieve: total >= this.config.retrievalThreshold,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Base-level Activation: B_i = ln(sum(t_j^(-d))) + B
|
|
45
|
+
* Power Law of Practice + Forgetting Curve
|
|
46
|
+
*/
|
|
47
|
+
computeBaseLevel(accessTimes) {
|
|
48
|
+
if (accessTimes.length === 0) {
|
|
49
|
+
return this.config.baseLevelConstant;
|
|
50
|
+
}
|
|
51
|
+
const d = this.config.decayRate;
|
|
52
|
+
let sum = 0;
|
|
53
|
+
for (const t of accessTimes) {
|
|
54
|
+
// 경과 시간이 0 이하이면 최소값 사용
|
|
55
|
+
const safeT = Math.max(t, CLAMP_MIN);
|
|
56
|
+
sum += Math.pow(safeT, -d);
|
|
57
|
+
}
|
|
58
|
+
// clamp sum to avoid log(0) or extreme values
|
|
59
|
+
sum = Math.max(sum, CLAMP_MIN);
|
|
60
|
+
sum = Math.min(sum, CLAMP_MAX);
|
|
61
|
+
return Math.log(sum) + this.config.baseLevelConstant;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Spreading Activation: S_i = sum(W_j * S_ji)
|
|
65
|
+
* Fan Effect: W_j = Smax / fan(j)
|
|
66
|
+
*/
|
|
67
|
+
computeSpreading(associations, context) {
|
|
68
|
+
if (associations.length === 0 || context.size === 0) {
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
// Fan 계산: 각 source가 연관된 총 수
|
|
72
|
+
const fanCounts = new Map();
|
|
73
|
+
for (const assoc of associations) {
|
|
74
|
+
fanCounts.set(assoc.source, (fanCounts.get(assoc.source) ?? 0) + 1);
|
|
75
|
+
}
|
|
76
|
+
let totalSpreading = 0;
|
|
77
|
+
for (const assoc of associations) {
|
|
78
|
+
if (!context.has(assoc.source))
|
|
79
|
+
continue;
|
|
80
|
+
const fan = fanCounts.get(assoc.source) ?? 1;
|
|
81
|
+
const W_j = this.config.maxAssociativeStrength / (fan * this.config.fanEffectFactor);
|
|
82
|
+
totalSpreading += W_j * assoc.strength;
|
|
83
|
+
}
|
|
84
|
+
return totalSpreading;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Partial Matching: P_i = -P * (1 - similarity)
|
|
88
|
+
*/
|
|
89
|
+
computePartialMatch(similarity) {
|
|
90
|
+
const clampedSim = Math.max(0, Math.min(1, similarity));
|
|
91
|
+
return -this.config.mismatchPenalty * (1 - clampedSim);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Activation을 1-maxLevel 레벨로 변환
|
|
95
|
+
*
|
|
96
|
+
* 정규화: activation [-2, 5] -> [0, 1]
|
|
97
|
+
* 레벨: ceil(normalized * maxLevel), clamp [1, maxLevel]
|
|
98
|
+
*/
|
|
99
|
+
computeLevel(activation, maxLevel) {
|
|
100
|
+
// 정규화: [-2, 5] 범위를 [0, 1]로
|
|
101
|
+
const normalized = Math.max(0, Math.min(1, (activation + 2) / 7));
|
|
102
|
+
const level = Math.ceil(normalized * maxLevel);
|
|
103
|
+
return Math.min(maxLevel, Math.max(1, level));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=actr-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actr-engine.js","sourceRoot":"","sources":["../../src/proficiency/actr-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proficiency Module
|
|
3
|
+
*
|
|
4
|
+
* ACT-R 기반 스킬 숙련도 추적 시스템.
|
|
5
|
+
*/
|
|
6
|
+
export { ACTREngine } from './actr-engine.js';
|
|
7
|
+
export { ProficiencyTracker, computePracticalLevel } from './tracker.js';
|
|
8
|
+
export type { ACTRConfig, ActivationResult, ExperienceEvent, ProficiencyRecord, LevelUpdateResult, SimulationScenario, } from './types.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/proficiency/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/proficiency/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proficiency Tracker
|
|
3
|
+
*
|
|
4
|
+
* 스킬 숙련도를 추적하고 레벨 계산을 수행하는 오케스트레이터.
|
|
5
|
+
*
|
|
6
|
+
* 레벨 공식 (Hybrid):
|
|
7
|
+
* countScore = log2(1 + N) / log2(151) // Power Law of Practice
|
|
8
|
+
* successScore = 0.3 + successRate * 0.7 // 성공률 반영
|
|
9
|
+
* recencyFactor = exp(-daysSince * 0.02) // ACT-R Forgetting Curve
|
|
10
|
+
* difficultyBonus = avgDifficulty * 0.1 // 난이도 보상
|
|
11
|
+
* level = ceil(clamp(countScore * successScore * recencyFactor + difficultyBonus, 0, 1) * maxLevel)
|
|
12
|
+
*
|
|
13
|
+
* ACT-R 순수 활성화 값은 actrActivation 필드에 별도 저장 (분석용).
|
|
14
|
+
*/
|
|
15
|
+
import type { MemoryDatabase } from '../db/database.js';
|
|
16
|
+
import type { ProficiencyConfig } from '../types/index.js';
|
|
17
|
+
import type { ProficiencyRecord, LevelUpdateResult, SimulationScenario } from './types.js';
|
|
18
|
+
export declare class ProficiencyTracker {
|
|
19
|
+
private db;
|
|
20
|
+
private config;
|
|
21
|
+
private engine;
|
|
22
|
+
constructor(db: MemoryDatabase, config: ProficiencyConfig);
|
|
23
|
+
/**
|
|
24
|
+
* 스킬 연습 기록 + 레벨 재계산
|
|
25
|
+
*/
|
|
26
|
+
recordPractice(skillMemoryId: string, outcome: 'success' | 'partial' | 'failure', difficulty: number, contextTags?: string[], sessionId?: string): LevelUpdateResult;
|
|
27
|
+
/**
|
|
28
|
+
* 레벨 재계산 (Hybrid: Power Law + Forgetting Curve)
|
|
29
|
+
*/
|
|
30
|
+
recalculateLevel(proficiencyId: string): LevelUpdateResult;
|
|
31
|
+
/**
|
|
32
|
+
* 숙련도 레코드 보장: 없으면 생성
|
|
33
|
+
*/
|
|
34
|
+
ensureProficiency(skillMemoryId: string): ProficiencyRecord;
|
|
35
|
+
/**
|
|
36
|
+
* 숙련도 목록 조회
|
|
37
|
+
*/
|
|
38
|
+
listProficiencies(projectPath?: string): ProficiencyRecord[];
|
|
39
|
+
/**
|
|
40
|
+
* 시뮬레이션: 이벤트 시퀀스 → 레벨 진행 반환
|
|
41
|
+
*/
|
|
42
|
+
simulate(scenario: SimulationScenario): number[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 실용적 레벨 공식
|
|
46
|
+
*
|
|
47
|
+
* Power Law of Practice (log 성장) + Forgetting Curve (지수 감쇠) + 난이도 보너스
|
|
48
|
+
*/
|
|
49
|
+
export declare function computePracticalLevel(experienceCount: number, successRate: number, daysSinceLastPractice: number, avgDifficulty: number, maxLevel: number): number;
|
|
50
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/proficiency/tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAMpB,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,EAAE,CAAiB;IAC3B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAAa;gBAEf,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB;IAMzD;;OAEG;IACH,cAAc,CACZ,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,EAC1C,UAAU,EAAE,MAAM,EAClB,WAAW,GAAE,MAAM,EAAO,EAC1B,SAAS,CAAC,EAAE,MAAM,GACjB,iBAAiB;IAgBpB;;OAEG;IACH,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB;IAwE1D;;OAEG;IACH,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB;IAiB3D;;OAEG;IACH,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAI5D;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,EAAE;CA2BjD;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,qBAAqB,EAAE,MAAM,EAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAiBR"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proficiency Tracker
|
|
3
|
+
*
|
|
4
|
+
* 스킬 숙련도를 추적하고 레벨 계산을 수행하는 오케스트레이터.
|
|
5
|
+
*
|
|
6
|
+
* 레벨 공식 (Hybrid):
|
|
7
|
+
* countScore = log2(1 + N) / log2(151) // Power Law of Practice
|
|
8
|
+
* successScore = 0.3 + successRate * 0.7 // 성공률 반영
|
|
9
|
+
* recencyFactor = exp(-daysSince * 0.02) // ACT-R Forgetting Curve
|
|
10
|
+
* difficultyBonus = avgDifficulty * 0.1 // 난이도 보상
|
|
11
|
+
* level = ceil(clamp(countScore * successScore * recencyFactor + difficultyBonus, 0, 1) * maxLevel)
|
|
12
|
+
*
|
|
13
|
+
* ACT-R 순수 활성화 값은 actrActivation 필드에 별도 저장 (분석용).
|
|
14
|
+
*/
|
|
15
|
+
import { ACTREngine } from './actr-engine.js';
|
|
16
|
+
// 150 이벤트에서 countScore ≈ 1.0 도달 (Power Law 스케일링)
|
|
17
|
+
const COUNT_SCALE = Math.log2(151);
|
|
18
|
+
export class ProficiencyTracker {
|
|
19
|
+
db;
|
|
20
|
+
config;
|
|
21
|
+
engine;
|
|
22
|
+
constructor(db, config) {
|
|
23
|
+
this.db = db;
|
|
24
|
+
this.config = config;
|
|
25
|
+
this.engine = new ACTREngine(config.actr);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 스킬 연습 기록 + 레벨 재계산
|
|
29
|
+
*/
|
|
30
|
+
recordPractice(skillMemoryId, outcome, difficulty, contextTags = [], sessionId) {
|
|
31
|
+
const proficiency = this.ensureProficiency(skillMemoryId);
|
|
32
|
+
const now = Date.now() / 1000;
|
|
33
|
+
this.db.addExperienceEvent({
|
|
34
|
+
proficiencyId: proficiency.id,
|
|
35
|
+
timestamp: now,
|
|
36
|
+
outcome,
|
|
37
|
+
difficulty: Math.max(0, Math.min(1, difficulty)),
|
|
38
|
+
contextTags,
|
|
39
|
+
sessionId,
|
|
40
|
+
});
|
|
41
|
+
return this.recalculateLevel(proficiency.id);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 레벨 재계산 (Hybrid: Power Law + Forgetting Curve)
|
|
45
|
+
*/
|
|
46
|
+
recalculateLevel(proficiencyId) {
|
|
47
|
+
const proficiency = this.db.getProficiency(proficiencyId);
|
|
48
|
+
if (!proficiency) {
|
|
49
|
+
return { previousLevel: 1, newLevel: 1, activation: 0, experienceCount: 0, levelChanged: false };
|
|
50
|
+
}
|
|
51
|
+
const events = this.db.getExperienceEvents(proficiencyId, { limit: 1000, order: 'desc' });
|
|
52
|
+
if (events.length === 0) {
|
|
53
|
+
return {
|
|
54
|
+
previousLevel: proficiency.level,
|
|
55
|
+
newLevel: 1,
|
|
56
|
+
activation: 0,
|
|
57
|
+
experienceCount: 0,
|
|
58
|
+
levelChanged: proficiency.level !== 1,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const now = Date.now() / 1000;
|
|
62
|
+
// 성공률
|
|
63
|
+
const successCount = events.filter((e) => e.outcome === 'success').length;
|
|
64
|
+
const partialCount = events.filter((e) => e.outcome === 'partial').length;
|
|
65
|
+
const successRate = (successCount + partialCount * 0.5) / events.length;
|
|
66
|
+
// 난이도
|
|
67
|
+
const avgDifficulty = events.reduce((sum, e) => sum + e.difficulty, 0) / events.length;
|
|
68
|
+
// 최근 연습 이후 경과일
|
|
69
|
+
const daysSinceLastPractice = (now - events[0].timestamp) / 86400;
|
|
70
|
+
// ACT-R 활성화 계산 (분석용 저장)
|
|
71
|
+
const accessTimes = events.map((e) => Math.max(now - e.timestamp, 1.0));
|
|
72
|
+
const tagCounts = new Map();
|
|
73
|
+
for (const event of events) {
|
|
74
|
+
for (const tag of event.contextTags) {
|
|
75
|
+
tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const associations = Array.from(tagCounts.entries()).map(([tag, count]) => ({
|
|
79
|
+
source: tag,
|
|
80
|
+
strength: Math.min(count / events.length, 1.0),
|
|
81
|
+
}));
|
|
82
|
+
const recentTags = events.slice(0, 5).flatMap((e) => e.contextTags);
|
|
83
|
+
const actrResult = this.engine.computeActivation(accessTimes, associations, new Set(recentTags), successRate, proficiencyId);
|
|
84
|
+
// 레벨 계산 (Hybrid)
|
|
85
|
+
const newLevel = computePracticalLevel(events.length, successRate, daysSinceLastPractice, avgDifficulty, this.config.maxLevel);
|
|
86
|
+
const previousLevel = proficiency.level;
|
|
87
|
+
const activation = actrResult.total + avgDifficulty * 0.2;
|
|
88
|
+
this.db.updateProficiency(proficiencyId, {
|
|
89
|
+
level: newLevel,
|
|
90
|
+
experienceCount: events.length,
|
|
91
|
+
successRate,
|
|
92
|
+
actrActivation: activation,
|
|
93
|
+
lastPracticedAt: new Date().toISOString(),
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
previousLevel,
|
|
97
|
+
newLevel,
|
|
98
|
+
activation,
|
|
99
|
+
experienceCount: events.length,
|
|
100
|
+
levelChanged: previousLevel !== newLevel,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 숙련도 레코드 보장: 없으면 생성
|
|
105
|
+
*/
|
|
106
|
+
ensureProficiency(skillMemoryId) {
|
|
107
|
+
const existing = this.db.getProficiencyBySkill(skillMemoryId);
|
|
108
|
+
if (existing)
|
|
109
|
+
return existing;
|
|
110
|
+
const skillMemory = this.db.getMemory(skillMemoryId);
|
|
111
|
+
const skillName = skillMemory
|
|
112
|
+
? skillMemory.content.split('\n')[0].replace('[Skill] ', '').slice(0, 100)
|
|
113
|
+
: `skill-${skillMemoryId.slice(0, 8)}`;
|
|
114
|
+
const projectPath = skillMemory?.projectPath;
|
|
115
|
+
return this.db.createProficiency({
|
|
116
|
+
skillMemoryId,
|
|
117
|
+
skillName,
|
|
118
|
+
projectPath,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 숙련도 목록 조회
|
|
123
|
+
*/
|
|
124
|
+
listProficiencies(projectPath) {
|
|
125
|
+
return this.db.listProficiencies({ projectPath });
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 시뮬레이션: 이벤트 시퀀스 → 레벨 진행 반환
|
|
129
|
+
*/
|
|
130
|
+
simulate(scenario) {
|
|
131
|
+
const levels = [];
|
|
132
|
+
let successCount = 0;
|
|
133
|
+
let totalDifficulty = 0;
|
|
134
|
+
for (let i = 0; i < scenario.eventCount; i++) {
|
|
135
|
+
const isSuccess = Math.random() < scenario.successRate;
|
|
136
|
+
if (isSuccess)
|
|
137
|
+
successCount++;
|
|
138
|
+
const totalCount = i + 1;
|
|
139
|
+
const successRate = successCount / totalCount;
|
|
140
|
+
const [minD, maxD] = scenario.difficultyRange;
|
|
141
|
+
const difficulty = minD + (maxD - minD) * (i / Math.max(scenario.eventCount - 1, 1));
|
|
142
|
+
totalDifficulty += difficulty;
|
|
143
|
+
const avgDifficulty = totalDifficulty / totalCount;
|
|
144
|
+
// 최근 연습 이후 경과일: 시뮬레이션에서는 0 (방금 연습)
|
|
145
|
+
const daysSinceLastPractice = 0;
|
|
146
|
+
const level = computePracticalLevel(totalCount, successRate, daysSinceLastPractice, avgDifficulty, this.config.maxLevel);
|
|
147
|
+
levels.push(level);
|
|
148
|
+
}
|
|
149
|
+
return levels;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* 실용적 레벨 공식
|
|
154
|
+
*
|
|
155
|
+
* Power Law of Practice (log 성장) + Forgetting Curve (지수 감쇠) + 난이도 보너스
|
|
156
|
+
*/
|
|
157
|
+
export function computePracticalLevel(experienceCount, successRate, daysSinceLastPractice, avgDifficulty, maxLevel) {
|
|
158
|
+
// 1. 연습 횟수 (Power Law - 대수적 성장)
|
|
159
|
+
const countScore = Math.min(1.0, Math.log2(1 + experienceCount) / COUNT_SCALE);
|
|
160
|
+
// 2. 성공률 (0% → 0.3, 100% → 1.0)
|
|
161
|
+
const successScore = 0.3 + successRate * 0.7;
|
|
162
|
+
// 3. 망각 곡선 (ACT-R inspired exponential decay)
|
|
163
|
+
const recencyFactor = Math.exp(-Math.max(0, daysSinceLastPractice) * 0.02);
|
|
164
|
+
// 4. 난이도 보너스 (높은 난이도 연습에 보상)
|
|
165
|
+
const difficultyBonus = avgDifficulty * 0.1;
|
|
166
|
+
// 합산
|
|
167
|
+
const combined = Math.max(0, Math.min(1, countScore * successScore * recencyFactor + difficultyBonus));
|
|
168
|
+
return Math.min(maxLevel, Math.max(1, Math.ceil(combined * maxLevel)));
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/proficiency/tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proficiency Types
|
|
3
|
+
*
|
|
4
|
+
* ACT-R 인지 아키텍처 기반 숙련도 추적 타입 정의.
|
|
5
|
+
* Power Law of Practice + Forgetting Curve를 활용한 레벨 1-10 자동 계산.
|
|
6
|
+
*/
|
|
7
|
+
export interface ACTRConfig {
|
|
8
|
+
decayRate: number;
|
|
9
|
+
baseLevelConstant: number;
|
|
10
|
+
maxAssociativeStrength: number;
|
|
11
|
+
fanEffectFactor: number;
|
|
12
|
+
mismatchPenalty: number;
|
|
13
|
+
retrievalThreshold: number;
|
|
14
|
+
}
|
|
15
|
+
export interface ActivationResult {
|
|
16
|
+
memoryId: string;
|
|
17
|
+
baseLevel: number;
|
|
18
|
+
spreading: number;
|
|
19
|
+
partialMatch: number;
|
|
20
|
+
total: number;
|
|
21
|
+
shouldRetrieve: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface ExperienceEvent {
|
|
24
|
+
id: string;
|
|
25
|
+
proficiencyId: string;
|
|
26
|
+
timestamp: number;
|
|
27
|
+
outcome: 'success' | 'partial' | 'failure';
|
|
28
|
+
difficulty: number;
|
|
29
|
+
contextTags: string[];
|
|
30
|
+
sessionId?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ProficiencyRecord {
|
|
33
|
+
id: string;
|
|
34
|
+
skillMemoryId: string;
|
|
35
|
+
skillName: string;
|
|
36
|
+
level: number;
|
|
37
|
+
experienceCount: number;
|
|
38
|
+
successRate: number;
|
|
39
|
+
actrActivation: number;
|
|
40
|
+
lastPracticedAt: string;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
updatedAt: string;
|
|
43
|
+
projectPath?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface LevelUpdateResult {
|
|
46
|
+
previousLevel: number;
|
|
47
|
+
newLevel: number;
|
|
48
|
+
activation: number;
|
|
49
|
+
experienceCount: number;
|
|
50
|
+
levelChanged: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface SimulationScenario {
|
|
53
|
+
eventCount: number;
|
|
54
|
+
successRate: number;
|
|
55
|
+
difficultyRange: [number, number];
|
|
56
|
+
timeSpanDays: number;
|
|
57
|
+
expectedMinLevel: number;
|
|
58
|
+
expectedMaxLevel: number;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/proficiency/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/proficiency/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-specific Memory Adapters (Plugin-side)
|
|
3
|
+
*
|
|
4
|
+
* 각 AI 프로바이더의 메모리 형식과 A2A 통합 형식 간 변환합니다.
|
|
5
|
+
*/
|
|
6
|
+
import type { MemoryCategory } from '../types/index.js';
|
|
7
|
+
import type { AIProvider } from './detector.js';
|
|
8
|
+
export interface UnifiedMemory {
|
|
9
|
+
id: string;
|
|
10
|
+
content: string;
|
|
11
|
+
category: MemoryCategory;
|
|
12
|
+
tags: string[];
|
|
13
|
+
metadata: Record<string, unknown>;
|
|
14
|
+
sourceProvider: string;
|
|
15
|
+
createdAt?: string;
|
|
16
|
+
confidence: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ProviderAdapter {
|
|
19
|
+
provider: AIProvider;
|
|
20
|
+
toUnified(data: Record<string, unknown>): UnifiedMemory;
|
|
21
|
+
fromUnified(memory: UnifiedMemory): Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Claude Memory Adapter
|
|
25
|
+
*/
|
|
26
|
+
export declare class ClaudeAdapter implements ProviderAdapter {
|
|
27
|
+
provider: AIProvider;
|
|
28
|
+
private static TYPE_TO_CATEGORY;
|
|
29
|
+
private static CATEGORY_TO_TYPE;
|
|
30
|
+
toUnified(data: Record<string, unknown>): UnifiedMemory;
|
|
31
|
+
fromUnified(memory: UnifiedMemory): Record<string, unknown>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* OpenAI GPT Memory Adapter
|
|
35
|
+
*/
|
|
36
|
+
export declare class GPTAdapter implements ProviderAdapter {
|
|
37
|
+
provider: AIProvider;
|
|
38
|
+
toUnified(data: Record<string, unknown>): UnifiedMemory;
|
|
39
|
+
fromUnified(memory: UnifiedMemory): Record<string, unknown>;
|
|
40
|
+
private inferCategory;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Gemini Memory Adapter
|
|
44
|
+
*/
|
|
45
|
+
export declare class GeminiAdapter implements ProviderAdapter {
|
|
46
|
+
provider: AIProvider;
|
|
47
|
+
toUnified(data: Record<string, unknown>): UnifiedMemory;
|
|
48
|
+
fromUnified(memory: UnifiedMemory): Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Adapter Factory
|
|
52
|
+
*/
|
|
53
|
+
export declare function createAdapter(provider: AIProvider): ProviderAdapter;
|
|
54
|
+
//# sourceMappingURL=adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/providers/adapters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,UAAU,CAAC;IACrB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAAC;IACxD,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7D;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,EAAE,UAAU,CAAY;IAEhC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAM7B;IAEF,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAM7B;IAEF,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAcvD,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAU5D;AAED;;GAEG;AACH,qBAAa,UAAW,YAAW,eAAe;IAChD,QAAQ,EAAE,UAAU,CAAY;IAEhC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAcvD,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAW3D,OAAO,CAAC,aAAa;CAQtB;AAED;;GAEG;AACH,qBAAa,aAAc,YAAW,eAAe;IACnD,QAAQ,EAAE,UAAU,CAAY;IAEhC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAoBvD,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAU5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,eAAe,CAWnE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-specific Memory Adapters (Plugin-side)
|
|
3
|
+
*
|
|
4
|
+
* 각 AI 프로바이더의 메모리 형식과 A2A 통합 형식 간 변환합니다.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Claude Memory Adapter
|
|
8
|
+
*/
|
|
9
|
+
export class ClaudeAdapter {
|
|
10
|
+
provider = 'claude';
|
|
11
|
+
static TYPE_TO_CATEGORY = {
|
|
12
|
+
error: 'error_solution',
|
|
13
|
+
pattern: 'code_pattern',
|
|
14
|
+
decision: 'decision',
|
|
15
|
+
preference: 'convention',
|
|
16
|
+
context: 'context',
|
|
17
|
+
};
|
|
18
|
+
static CATEGORY_TO_TYPE = {
|
|
19
|
+
error_solution: 'error',
|
|
20
|
+
code_pattern: 'pattern',
|
|
21
|
+
decision: 'decision',
|
|
22
|
+
convention: 'preference',
|
|
23
|
+
context: 'context',
|
|
24
|
+
};
|
|
25
|
+
toUnified(data) {
|
|
26
|
+
const type = data.type ?? 'context';
|
|
27
|
+
return {
|
|
28
|
+
id: data.id ?? '',
|
|
29
|
+
content: data.content ?? '',
|
|
30
|
+
category: ClaudeAdapter.TYPE_TO_CATEGORY[type] ?? 'context',
|
|
31
|
+
tags: data.tags ?? [],
|
|
32
|
+
metadata: { originalType: type },
|
|
33
|
+
sourceProvider: 'claude',
|
|
34
|
+
createdAt: data.created_at,
|
|
35
|
+
confidence: data.confidence ?? 1.0,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
fromUnified(memory) {
|
|
39
|
+
return {
|
|
40
|
+
id: memory.id,
|
|
41
|
+
content: memory.content,
|
|
42
|
+
type: ClaudeAdapter.CATEGORY_TO_TYPE[memory.category] ?? 'context',
|
|
43
|
+
tags: memory.tags,
|
|
44
|
+
created_at: memory.createdAt,
|
|
45
|
+
confidence: memory.confidence,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* OpenAI GPT Memory Adapter
|
|
51
|
+
*/
|
|
52
|
+
export class GPTAdapter {
|
|
53
|
+
provider = 'openai';
|
|
54
|
+
toUnified(data) {
|
|
55
|
+
const content = data.content ?? data.value ?? '';
|
|
56
|
+
return {
|
|
57
|
+
id: data.id ?? '',
|
|
58
|
+
content,
|
|
59
|
+
category: this.inferCategory(content),
|
|
60
|
+
tags: data.tags ?? [],
|
|
61
|
+
metadata: { originalType: data.type },
|
|
62
|
+
sourceProvider: 'openai',
|
|
63
|
+
createdAt: data.created_at,
|
|
64
|
+
confidence: data.confidence ?? 1.0,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
fromUnified(memory) {
|
|
68
|
+
return {
|
|
69
|
+
id: memory.id,
|
|
70
|
+
type: 'memory',
|
|
71
|
+
value: memory.content,
|
|
72
|
+
tags: memory.tags,
|
|
73
|
+
metadata: { category: memory.category, source: memory.sourceProvider },
|
|
74
|
+
created_at: memory.createdAt,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
inferCategory(content) {
|
|
78
|
+
const lower = content.toLowerCase();
|
|
79
|
+
if (['error', 'fix', 'bug'].some((kw) => lower.includes(kw)))
|
|
80
|
+
return 'error_solution';
|
|
81
|
+
if (['pattern', 'template'].some((kw) => lower.includes(kw)))
|
|
82
|
+
return 'code_pattern';
|
|
83
|
+
if (['decided', 'chose', 'decision'].some((kw) => lower.includes(kw)))
|
|
84
|
+
return 'decision';
|
|
85
|
+
if (['always', 'never', 'prefer'].some((kw) => lower.includes(kw)))
|
|
86
|
+
return 'convention';
|
|
87
|
+
return 'context';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gemini Memory Adapter
|
|
92
|
+
*/
|
|
93
|
+
export class GeminiAdapter {
|
|
94
|
+
provider = 'gemini';
|
|
95
|
+
toUnified(data) {
|
|
96
|
+
let content = '';
|
|
97
|
+
if (typeof data.content === 'string') {
|
|
98
|
+
content = data.content;
|
|
99
|
+
}
|
|
100
|
+
else if (typeof data.content === 'object' && data.content !== null) {
|
|
101
|
+
content = data.content.text ?? '';
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
id: data.id ?? '',
|
|
105
|
+
content,
|
|
106
|
+
category: data.category ?? 'context',
|
|
107
|
+
tags: data.labels ?? [],
|
|
108
|
+
metadata: { cacheId: data.cache_id },
|
|
109
|
+
sourceProvider: 'gemini',
|
|
110
|
+
createdAt: data.create_time,
|
|
111
|
+
confidence: data.confidence ?? 1.0,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
fromUnified(memory) {
|
|
115
|
+
return {
|
|
116
|
+
id: memory.id,
|
|
117
|
+
content: { text: memory.content },
|
|
118
|
+
category: memory.category,
|
|
119
|
+
labels: memory.tags,
|
|
120
|
+
metadata: { source: memory.sourceProvider },
|
|
121
|
+
create_time: memory.createdAt,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Adapter Factory
|
|
127
|
+
*/
|
|
128
|
+
export function createAdapter(provider) {
|
|
129
|
+
switch (provider) {
|
|
130
|
+
case 'claude':
|
|
131
|
+
return new ClaudeAdapter();
|
|
132
|
+
case 'openai':
|
|
133
|
+
return new GPTAdapter();
|
|
134
|
+
case 'gemini':
|
|
135
|
+
return new GeminiAdapter();
|
|
136
|
+
default:
|
|
137
|
+
return new ClaudeAdapter(); // Default to Claude
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=adapters.js.map
|