@jungjaehoon/mama-core 1.1.2 → 1.1.3
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/config-loader.d.ts +61 -0
- package/dist/config-loader.js +187 -0
- package/dist/db-adapter/base-adapter.d.ts +76 -0
- package/dist/db-adapter/base-adapter.js +11 -0
- package/dist/db-adapter/index.d.ts +24 -0
- package/dist/db-adapter/index.js +29 -0
- package/dist/db-adapter/sqlite-adapter.d.ts +73 -0
- package/dist/db-adapter/sqlite-adapter.js +330 -0
- package/dist/db-adapter/statement.d.ts +119 -0
- package/dist/db-adapter/statement.js +113 -0
- package/dist/db-manager.d.ts +252 -0
- package/dist/db-manager.js +622 -0
- package/dist/debug-logger.d.ts +32 -0
- package/dist/debug-logger.js +83 -0
- package/dist/decision-formatter.d.ts +172 -0
- package/dist/decision-formatter.js +894 -0
- package/dist/decision-tracker.d.ts +218 -0
- package/dist/decision-tracker.js +531 -0
- package/dist/embedding-cache.d.ts +83 -0
- package/dist/embedding-cache.js +182 -0
- package/dist/embedding-client.d.ts +43 -0
- package/dist/embedding-client.js +132 -0
- package/dist/embedding-server/index.d.ts +65 -0
- package/dist/embedding-server/index.js +397 -0
- package/dist/embedding-server/mobile/auth.d.ts +53 -0
- package/dist/embedding-server/mobile/auth.js +140 -0
- package/dist/embedding-server/mobile/daemon.d.ts +128 -0
- package/dist/embedding-server/mobile/daemon.js +303 -0
- package/dist/embedding-server/mobile/output-parser.d.ts +115 -0
- package/dist/embedding-server/mobile/output-parser.js +241 -0
- package/dist/embedding-server/mobile/session-api.d.ts +57 -0
- package/dist/embedding-server/mobile/session-api.js +261 -0
- package/dist/embedding-server/mobile/session-manager.d.ts +135 -0
- package/dist/embedding-server/mobile/session-manager.js +333 -0
- package/dist/embedding-server/mobile/websocket-handler.d.ts +127 -0
- package/dist/embedding-server/mobile/websocket-handler.js +435 -0
- package/dist/embeddings.d.ts +75 -0
- package/dist/embeddings.js +262 -0
- package/dist/errors.d.ts +131 -0
- package/dist/errors.js +225 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +193 -0
- package/dist/mama-api.d.ts +954 -0
- package/dist/mama-api.js +2210 -0
- package/dist/memory-inject.d.ts +24 -0
- package/dist/memory-inject.js +116 -0
- package/dist/memory-store.d.ts +103 -0
- package/dist/memory-store.js +129 -0
- package/dist/notification-manager.d.ts +7 -0
- package/dist/notification-manager.js +12 -0
- package/dist/ollama-client.d.ts +51 -0
- package/dist/ollama-client.js +308 -0
- package/dist/outcome-tracker.d.ts +165 -0
- package/dist/outcome-tracker.js +315 -0
- package/dist/progress-indicator.d.ts +48 -0
- package/dist/progress-indicator.js +82 -0
- package/dist/query-intent.d.ts +27 -0
- package/dist/query-intent.js +144 -0
- package/dist/relevance-scorer.d.ts +124 -0
- package/dist/relevance-scorer.js +243 -0
- package/dist/test-utils.d.ts +66 -0
- package/dist/test-utils.js +166 -0
- package/dist/tier-validator.d.ts +55 -0
- package/dist/tier-validator.js +216 -0
- package/dist/time-formatter.d.ts +25 -0
- package/dist/time-formatter.js +93 -0
- package/package.json +3 -2
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MAMA (Memory-Augmented MCP Architecture) - Ollama Client Wrapper
|
|
4
|
+
*
|
|
5
|
+
* Simple wrapper for Ollama API with EXAONE 3.5 support
|
|
6
|
+
*
|
|
7
|
+
* @module ollama-client
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.FALLBACK_MODEL = exports.DEFAULT_MODEL = void 0;
|
|
14
|
+
exports.generate = generate;
|
|
15
|
+
exports.analyzeDecision = analyzeDecision;
|
|
16
|
+
exports.analyzeQueryIntent = analyzeQueryIntent;
|
|
17
|
+
exports.isAvailable = isAvailable;
|
|
18
|
+
exports.listModels = listModels;
|
|
19
|
+
const http_1 = __importDefault(require("http"));
|
|
20
|
+
const debug_logger_js_1 = require("./debug-logger.js");
|
|
21
|
+
// Ollama configuration
|
|
22
|
+
const OLLAMA_HOST = process.env.OLLAMA_HOST || 'localhost';
|
|
23
|
+
const OLLAMA_PORT = parseInt(process.env.OLLAMA_PORT || '11434', 10);
|
|
24
|
+
exports.DEFAULT_MODEL = 'exaone3.5:2.4b';
|
|
25
|
+
exports.FALLBACK_MODEL = 'gemma:2b';
|
|
26
|
+
/**
|
|
27
|
+
* Call Ollama API
|
|
28
|
+
*/
|
|
29
|
+
function callOllamaAPI(endpoint, payload, timeout = 30000) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const postData = JSON.stringify(payload);
|
|
32
|
+
const options = {
|
|
33
|
+
hostname: OLLAMA_HOST,
|
|
34
|
+
port: OLLAMA_PORT,
|
|
35
|
+
path: endpoint,
|
|
36
|
+
method: 'POST',
|
|
37
|
+
headers: {
|
|
38
|
+
'Content-Type': 'application/json',
|
|
39
|
+
'Content-Length': Buffer.byteLength(postData),
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
const req = http_1.default.request(options, (res) => {
|
|
43
|
+
let data = '';
|
|
44
|
+
res.on('data', (chunk) => {
|
|
45
|
+
data += chunk;
|
|
46
|
+
});
|
|
47
|
+
res.on('end', () => {
|
|
48
|
+
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
|
|
49
|
+
try {
|
|
50
|
+
// Ollama returns NDJSON (newline-delimited JSON)
|
|
51
|
+
const lines = data.trim().split('\n');
|
|
52
|
+
const response = JSON.parse(lines[lines.length - 1]);
|
|
53
|
+
resolve(response);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
57
|
+
reject(new Error(`Failed to parse Ollama response: ${message}`));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
reject(new Error(`Ollama API error: ${res.statusCode} - ${data}`));
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
req.on('error', (error) => {
|
|
66
|
+
reject(new Error(`Ollama connection failed: ${error.message}`));
|
|
67
|
+
});
|
|
68
|
+
req.setTimeout(timeout, () => {
|
|
69
|
+
req.destroy();
|
|
70
|
+
reject(new Error(`Ollama request timeout (${timeout}ms)`));
|
|
71
|
+
});
|
|
72
|
+
req.write(postData);
|
|
73
|
+
req.end();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Generate text with EXAONE 3.5
|
|
78
|
+
*/
|
|
79
|
+
async function generate(prompt, options = {}) {
|
|
80
|
+
const { model = exports.DEFAULT_MODEL, format = null, temperature = 0.7, max_tokens = 500, timeout = 30000, } = options;
|
|
81
|
+
const payload = {
|
|
82
|
+
model,
|
|
83
|
+
prompt,
|
|
84
|
+
stream: false,
|
|
85
|
+
options: {
|
|
86
|
+
temperature,
|
|
87
|
+
num_predict: max_tokens,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
if (format === 'json') {
|
|
91
|
+
payload.format = 'json';
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const response = await callOllamaAPI('/api/generate', payload, timeout);
|
|
95
|
+
// Extract response text
|
|
96
|
+
const responseText = response.response;
|
|
97
|
+
// Parse JSON if requested
|
|
98
|
+
if (format === 'json') {
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(responseText);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
throw new Error(`Failed to parse JSON response: ${responseText}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return responseText;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
110
|
+
// Try fallback model if EXAONE fails
|
|
111
|
+
const isModelNotFound = /model ['"].*['"] not found/i.test(message) ||
|
|
112
|
+
(message.includes('404') && message.toLowerCase().includes('not found'));
|
|
113
|
+
if (model === exports.DEFAULT_MODEL && isModelNotFound) {
|
|
114
|
+
(0, debug_logger_js_1.error)(`[MAMA] EXAONE not found, trying fallback (${exports.FALLBACK_MODEL})...`);
|
|
115
|
+
return generate(prompt, {
|
|
116
|
+
...options,
|
|
117
|
+
model: exports.FALLBACK_MODEL,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Validate DecisionAnalysisResult shape at runtime
|
|
125
|
+
*/
|
|
126
|
+
function isDecisionAnalysisResult(obj) {
|
|
127
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
const o = obj;
|
|
131
|
+
return (typeof o.is_decision === 'boolean' &&
|
|
132
|
+
(typeof o.topic === 'string' || o.topic === null) &&
|
|
133
|
+
(typeof o.decision === 'string' || o.decision === null) &&
|
|
134
|
+
typeof o.reasoning === 'string' &&
|
|
135
|
+
typeof o.confidence === 'number');
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Validate QueryIntentResult shape at runtime
|
|
139
|
+
*/
|
|
140
|
+
function isQueryIntentResult(obj) {
|
|
141
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
const o = obj;
|
|
145
|
+
return (typeof o.involves_decision === 'boolean' &&
|
|
146
|
+
(typeof o.topic === 'string' || o.topic === null) &&
|
|
147
|
+
(o.query_type === 'recall' || o.query_type === 'evolution' || o.query_type === 'none') &&
|
|
148
|
+
typeof o.reasoning === 'string');
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Analyze decision from tool execution
|
|
152
|
+
*/
|
|
153
|
+
async function analyzeDecision(toolExecution, sessionContext) {
|
|
154
|
+
const prompt = `
|
|
155
|
+
Analyze if this represents a DECISION (not just an action):
|
|
156
|
+
|
|
157
|
+
Session Context:
|
|
158
|
+
- Latest User Message: ${sessionContext.latest_user_message || 'N/A'}
|
|
159
|
+
- Recent Exchange: ${sessionContext.recent_exchange || 'N/A'}
|
|
160
|
+
|
|
161
|
+
Tool Execution:
|
|
162
|
+
- Tool: ${toolExecution.tool_name ?? 'N/A'}
|
|
163
|
+
- Input: ${JSON.stringify(toolExecution.tool_input ?? null)}
|
|
164
|
+
- Result: ${toolExecution.exit_code !== undefined ? (toolExecution.exit_code === 0 ? 'SUCCESS' : 'FAILED') : 'UNKNOWN'}
|
|
165
|
+
|
|
166
|
+
Decision Indicators:
|
|
167
|
+
1. User explicitly chose between alternatives?
|
|
168
|
+
Example: "Let's use JWT" (not "Use JWT" - that's just action)
|
|
169
|
+
|
|
170
|
+
2. User changed previous approach?
|
|
171
|
+
Example: "Complex → Simple approach"
|
|
172
|
+
|
|
173
|
+
3. User expressed preference?
|
|
174
|
+
Example: "Let's do it this way from now", "This approach is better"
|
|
175
|
+
|
|
176
|
+
4. Significant architectural choice?
|
|
177
|
+
Example: "Mesh structure: COMPLEX", "Authentication: JWT"
|
|
178
|
+
|
|
179
|
+
Is this a DECISION? Return JSON with "topic" as a short snake_case identifier:
|
|
180
|
+
{
|
|
181
|
+
"is_decision": boolean,
|
|
182
|
+
"topic": string or null (extract main technical topic in snake_case, e.g., "mesh_structure", "database_choice", "auth_strategy"),
|
|
183
|
+
"decision": string or null (the actual choice made, e.g., "COMPLEX", "PostgreSQL", "JWT"),
|
|
184
|
+
"reasoning": "Why this is/isn't a decision",
|
|
185
|
+
"confidence": 0.0-1.0
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
IMPORTANT: Generate "topic" freely based on context. Do NOT limit to predefined values.
|
|
189
|
+
`;
|
|
190
|
+
try {
|
|
191
|
+
const response = await generate(prompt, {
|
|
192
|
+
format: 'json',
|
|
193
|
+
temperature: 0.3,
|
|
194
|
+
max_tokens: 300,
|
|
195
|
+
});
|
|
196
|
+
if (!isDecisionAnalysisResult(response)) {
|
|
197
|
+
throw new Error('Invalid LLM response shape for DecisionAnalysisResult');
|
|
198
|
+
}
|
|
199
|
+
return response;
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
203
|
+
(0, debug_logger_js_1.error)(`[MAMA] Decision analysis FAILED: ${message}`);
|
|
204
|
+
throw new Error(`Decision analysis failed: ${message}`);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Analyze query intent
|
|
209
|
+
*/
|
|
210
|
+
async function analyzeQueryIntent(userMessage) {
|
|
211
|
+
const prompt = `
|
|
212
|
+
Analyze this user message to determine if it involves past decisions:
|
|
213
|
+
|
|
214
|
+
User Message: "${userMessage}"
|
|
215
|
+
|
|
216
|
+
Questions to answer:
|
|
217
|
+
1. Does this query reference past decisions or choices?
|
|
218
|
+
2. Is the user asking about previous approaches?
|
|
219
|
+
3. What topic is being discussed? (e.g., "mesh_structure", "authentication", "testing")
|
|
220
|
+
|
|
221
|
+
Return JSON:
|
|
222
|
+
{
|
|
223
|
+
"involves_decision": boolean,
|
|
224
|
+
"topic": "topic_name" | null,
|
|
225
|
+
"query_type": "recall" | "evolution" | "none",
|
|
226
|
+
"reasoning": "Why this involves/doesn't involve decisions"
|
|
227
|
+
}
|
|
228
|
+
`;
|
|
229
|
+
try {
|
|
230
|
+
const response = await generate(prompt, {
|
|
231
|
+
format: 'json',
|
|
232
|
+
temperature: 0.3,
|
|
233
|
+
max_tokens: 200,
|
|
234
|
+
});
|
|
235
|
+
if (!isQueryIntentResult(response)) {
|
|
236
|
+
throw new Error('Invalid LLM response shape for QueryIntentResult');
|
|
237
|
+
}
|
|
238
|
+
return response;
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
242
|
+
(0, debug_logger_js_1.error)(`[MAMA] Query intent analysis FAILED: ${message}`);
|
|
243
|
+
throw new Error(`Query intent analysis failed: ${message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Check if Ollama is available
|
|
248
|
+
*/
|
|
249
|
+
async function isAvailable() {
|
|
250
|
+
return new Promise((resolve) => {
|
|
251
|
+
const options = {
|
|
252
|
+
hostname: OLLAMA_HOST,
|
|
253
|
+
port: OLLAMA_PORT,
|
|
254
|
+
path: '/api/tags',
|
|
255
|
+
method: 'GET',
|
|
256
|
+
timeout: 2000,
|
|
257
|
+
};
|
|
258
|
+
const req = http_1.default.request(options, (res) => {
|
|
259
|
+
res.resume(); // Drain response body to release socket back to pool
|
|
260
|
+
resolve(res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300);
|
|
261
|
+
});
|
|
262
|
+
req.on('error', () => resolve(false));
|
|
263
|
+
req.on('timeout', () => {
|
|
264
|
+
req.destroy();
|
|
265
|
+
resolve(false);
|
|
266
|
+
});
|
|
267
|
+
req.end();
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* List available models
|
|
272
|
+
*/
|
|
273
|
+
async function listModels() {
|
|
274
|
+
return new Promise((resolve, reject) => {
|
|
275
|
+
const options = {
|
|
276
|
+
hostname: OLLAMA_HOST,
|
|
277
|
+
port: OLLAMA_PORT,
|
|
278
|
+
path: '/api/tags',
|
|
279
|
+
method: 'GET',
|
|
280
|
+
timeout: 5000,
|
|
281
|
+
};
|
|
282
|
+
const req = http_1.default.request(options, (res) => {
|
|
283
|
+
let data = '';
|
|
284
|
+
res.on('data', (chunk) => {
|
|
285
|
+
data += chunk;
|
|
286
|
+
});
|
|
287
|
+
res.on('end', () => {
|
|
288
|
+
try {
|
|
289
|
+
const response = JSON.parse(data);
|
|
290
|
+
resolve(response.models?.map((m) => m.name) || []);
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
294
|
+
reject(new Error(`Failed to parse models response: ${message}`));
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
req.on('error', (error) => {
|
|
299
|
+
reject(new Error(`Failed to list models: ${error.message}`));
|
|
300
|
+
});
|
|
301
|
+
req.on('timeout', () => {
|
|
302
|
+
req.destroy();
|
|
303
|
+
reject(new Error('List models timeout'));
|
|
304
|
+
});
|
|
305
|
+
req.end();
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=ollama-client.js.map
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MAMA (Memory-Augmented MCP Architecture) - Outcome Tracker
|
|
3
|
+
*
|
|
4
|
+
* Track decision outcomes from user feedback
|
|
5
|
+
* Tasks: 4.1-4.8 (Failure/success indicators, UserPromptSubmit analysis, outcome marking)
|
|
6
|
+
* AC #3: Failure tracking (user feedback → outcome marked, failure_reason extracted, duration calculated)
|
|
7
|
+
*
|
|
8
|
+
* @module outcome-tracker
|
|
9
|
+
* @version 1.0
|
|
10
|
+
* @date 2025-11-14
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Decision record from database
|
|
14
|
+
*/
|
|
15
|
+
interface DecisionRecord {
|
|
16
|
+
id: string;
|
|
17
|
+
topic: string;
|
|
18
|
+
decision: string;
|
|
19
|
+
outcome?: string | null;
|
|
20
|
+
confidence?: number;
|
|
21
|
+
created_at: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Hook context from Claude Code
|
|
25
|
+
*/
|
|
26
|
+
export interface HookContext {
|
|
27
|
+
user_message?: string;
|
|
28
|
+
session_id?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Failure indicators
|
|
32
|
+
* Task 4.2: Define failure indicators
|
|
33
|
+
*/
|
|
34
|
+
export declare const FAILURE_INDICATORS: RegExp[];
|
|
35
|
+
/**
|
|
36
|
+
* Success indicators
|
|
37
|
+
* Task 4.3: Define success indicators
|
|
38
|
+
*/
|
|
39
|
+
export declare const SUCCESS_INDICATORS: RegExp[];
|
|
40
|
+
/**
|
|
41
|
+
* Partial success indicators
|
|
42
|
+
* Task 4.3: Define partial success indicators
|
|
43
|
+
*/
|
|
44
|
+
export declare const PARTIAL_INDICATORS: RegExp[];
|
|
45
|
+
/**
|
|
46
|
+
* Recent decision time window (1 hour in milliseconds)
|
|
47
|
+
* Task 4.5: Only mark outcome if decision is recent (< 1 hour)
|
|
48
|
+
*/
|
|
49
|
+
export declare const RECENT_WINDOW_MS: number;
|
|
50
|
+
/**
|
|
51
|
+
* Check if message matches failure indicators
|
|
52
|
+
*
|
|
53
|
+
* Task 4.2: Match failure patterns
|
|
54
|
+
*
|
|
55
|
+
* @param message - User message
|
|
56
|
+
* @returns True if failure detected
|
|
57
|
+
*/
|
|
58
|
+
export declare function matchesFailureIndicators(message: string): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Check if message matches success indicators
|
|
61
|
+
*
|
|
62
|
+
* Task 4.3: Match success patterns
|
|
63
|
+
*
|
|
64
|
+
* @param message - User message
|
|
65
|
+
* @returns True if success detected
|
|
66
|
+
*/
|
|
67
|
+
export declare function matchesSuccessIndicators(message: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Check if message matches partial success indicators
|
|
70
|
+
*
|
|
71
|
+
* Task 4.3: Match partial success patterns
|
|
72
|
+
*
|
|
73
|
+
* @param message - User message
|
|
74
|
+
* @returns True if partial success detected
|
|
75
|
+
*/
|
|
76
|
+
export declare function matchesPartialIndicators(message: string): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Outcome type from analysis
|
|
79
|
+
*/
|
|
80
|
+
export type OutcomeType = 'FAILED' | 'SUCCESS' | 'PARTIAL';
|
|
81
|
+
/**
|
|
82
|
+
* Determine outcome from user message
|
|
83
|
+
*
|
|
84
|
+
* Task 4.4, 4.5: Analyze user message for indicators
|
|
85
|
+
* AC #3: Failure tracking from user feedback
|
|
86
|
+
*
|
|
87
|
+
* @param message - User message
|
|
88
|
+
* @returns Outcome type ('FAILED', 'SUCCESS', 'PARTIAL') or null
|
|
89
|
+
*/
|
|
90
|
+
export declare function analyzeOutcome(message: string): OutcomeType | null;
|
|
91
|
+
/**
|
|
92
|
+
* Extract failure reason from user message
|
|
93
|
+
*
|
|
94
|
+
* Task 4.6: Extract failure_reason from user message
|
|
95
|
+
* AC #3: failure_reason extracted
|
|
96
|
+
*
|
|
97
|
+
* Simple extraction: First sentence or first 200 characters
|
|
98
|
+
* Future: Use LLM for better extraction
|
|
99
|
+
*
|
|
100
|
+
* @param message - User message
|
|
101
|
+
* @param outcome - Outcome type
|
|
102
|
+
* @returns Failure reason
|
|
103
|
+
*/
|
|
104
|
+
export declare function extractFailureReason(message: string, outcome: OutcomeType | null): string | null;
|
|
105
|
+
/**
|
|
106
|
+
* Get recent decision (within 1 hour)
|
|
107
|
+
*
|
|
108
|
+
* Task 4.5: Find recent decision (< 1 hour)
|
|
109
|
+
* AC #3: Recent decision (< 1 hour) marked
|
|
110
|
+
*
|
|
111
|
+
* @param sessionId - Session ID
|
|
112
|
+
* @returns Recent decision or null
|
|
113
|
+
*/
|
|
114
|
+
export declare function getRecentDecision(sessionId: string): DecisionRecord | null;
|
|
115
|
+
/**
|
|
116
|
+
* Calculate duration in days
|
|
117
|
+
*
|
|
118
|
+
* Task 4.7: Calculate duration_days
|
|
119
|
+
* AC #3: duration_days calculated
|
|
120
|
+
*
|
|
121
|
+
* @param createdAt - Decision created timestamp
|
|
122
|
+
* @returns Duration in days
|
|
123
|
+
*/
|
|
124
|
+
export declare function calculateDurationDays(createdAt: number): number;
|
|
125
|
+
/**
|
|
126
|
+
* Get evidence impact for outcome
|
|
127
|
+
*
|
|
128
|
+
* Task 6: Confidence evolution - Calculate impact based on outcome
|
|
129
|
+
* AC #5: Confidence score calculated based on history
|
|
130
|
+
*
|
|
131
|
+
* @param outcome - Outcome type ('FAILED', 'SUCCESS', 'PARTIAL')
|
|
132
|
+
* @param durationDays - Duration in days
|
|
133
|
+
* @returns Impact on confidence
|
|
134
|
+
*/
|
|
135
|
+
export declare function getEvidenceImpact(outcome: OutcomeType, durationDays: number): number;
|
|
136
|
+
/**
|
|
137
|
+
* Mark decision outcome
|
|
138
|
+
*
|
|
139
|
+
* Task 4.8: Update decision row with outcome, failure_reason, duration_days
|
|
140
|
+
* Task 6.5: Update confidence when outcome is marked
|
|
141
|
+
* AC #3: Outcome marked with failure_reason and duration_days
|
|
142
|
+
* AC #5: Confidence evolution
|
|
143
|
+
*
|
|
144
|
+
* @param decisionId - Decision ID
|
|
145
|
+
* @param outcome - Outcome type ('FAILED', 'SUCCESS', 'PARTIAL')
|
|
146
|
+
* @param failureReason - Failure reason (if outcome=FAILED)
|
|
147
|
+
* @param durationDays - Duration in days
|
|
148
|
+
*/
|
|
149
|
+
export declare function markOutcome(decisionId: string, outcome: OutcomeType, failureReason: string | null, durationDays: number): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* UserPromptSubmit Handler
|
|
152
|
+
*
|
|
153
|
+
* Task 4.4: On UserPromptSubmit, analyze user message for indicators
|
|
154
|
+
* Task 4.5: If matches + recent decision (< 1 hour), mark outcome
|
|
155
|
+
* Task 4.6: Extract failure_reason from user message
|
|
156
|
+
* Task 4.7: Calculate duration_days
|
|
157
|
+
* Task 4.8: Update decision row
|
|
158
|
+
*
|
|
159
|
+
* AC #3: Failure tracking (user feedback → outcome marked)
|
|
160
|
+
*
|
|
161
|
+
* @param hookContext - Hook context from Claude Code
|
|
162
|
+
*/
|
|
163
|
+
export declare function onUserPromptSubmit(hookContext: HookContext): Promise<void>;
|
|
164
|
+
export {};
|
|
165
|
+
//# sourceMappingURL=outcome-tracker.d.ts.map
|