fix: address PR #317 code review feedback

**Critical Fixes:**
- Replace happy_path_error__with_fallback debug calls with proper logger methods in mcp-server.ts
- All HTTP API calls now use logger.debug/error for consistent logging

**Code Quality Improvements:**
- Extract 90-day recency window magic numbers to named constants
- Added RECENCY_WINDOW_DAYS and RECENCY_WINDOW_MS constants in SearchManager

**Documentation:**
- Document model cost implications of Haiku → Sonnet upgrade in CHANGELOG
- Provide clear migration path for users who want to revert to Haiku

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2025-12-14 21:40:23 -05:00
parent 9d509e07f5
commit ace12f8cd7
5 changed files with 97 additions and 73 deletions
+22
View File
@@ -24,6 +24,28 @@ Fixed critical bug where timeline tools were completely non-functional due to pa
- New `get_batch_observations` MCP tool for efficiently fetching multiple observations in a single request
- Enhanced SessionStore methods for fetching prompts and session summaries by ID
### Changed
**Default Model Upgrade: Haiku → Sonnet**
The default model for observations and summaries has been upgraded from `claude-haiku-4-5` to `claude-sonnet-4-5` for significantly improved quality.
**Impact on Costs:**
- Sonnet is approximately 5-10x more expensive than Haiku
- Better observation quality and more accurate context summaries
- **Recommendation**: Review your usage patterns and consider adjusting `CLAUDE_MEM_MODEL` in `~/.claude-mem/settings.json` if cost is a concern
**To revert to Haiku (lower cost):**
```json
{
"CLAUDE_MEM_MODEL": "claude-haiku-4-5"
}
```
**Code Quality:**
- Extracted magic numbers to constants (`RECENCY_WINDOW_DAYS`, `RECENCY_WINDOW_MS`)
- Replaced debug logging calls with proper logger methods
---
## [7.2.1] - 2025-12-14
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -87,7 +87,7 @@ async function callWorkerAPIWithPath(
endpoint: string,
id: number
): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {
happy_path_error__with_fallback('[mcp-server] → Worker API (path)', { endpoint, id });
logger.debug('HTTP', 'Worker API request (path)', undefined, { endpoint, id });
try {
const url = `${WORKER_BASE_URL}${endpoint}/${id}`;
@@ -100,7 +100,7 @@ async function callWorkerAPIWithPath(
const data = await response.json();
happy_path_error__with_fallback('[mcp-server] ← Worker API success (path)', { endpoint, id });
logger.debug('HTTP', 'Worker API success (path)', undefined, { endpoint, id });
// Wrap raw data in MCP format
return {
@@ -110,7 +110,7 @@ async function callWorkerAPIWithPath(
}]
};
} catch (error: any) {
happy_path_error__with_fallback('[mcp-server] ← Worker API error (path)', { endpoint, id, error: error.message });
logger.error('HTTP', 'Worker API error (path)', undefined, { endpoint, id, error: error.message });
return {
content: [{
type: 'text' as const,
@@ -128,7 +128,7 @@ async function callWorkerAPIPost(
endpoint: string,
body: Record<string, any>
): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {
happy_path_error__with_fallback('[mcp-server] → Worker API (POST)', { endpoint, body });
logger.debug('HTTP', 'Worker API request (POST)', undefined, { endpoint });
try {
const url = `${WORKER_BASE_URL}${endpoint}`;
@@ -147,7 +147,7 @@ async function callWorkerAPIPost(
const data = await response.json();
happy_path_error__with_fallback('[mcp-server] ← Worker API success (POST)', { endpoint });
logger.debug('HTTP', 'Worker API success (POST)', undefined, { endpoint });
// Wrap raw data in MCP format
return {
@@ -157,7 +157,7 @@ async function callWorkerAPIPost(
}]
};
} catch (error: any) {
happy_path_error__with_fallback('[mcp-server] ← Worker API error (POST)', { endpoint, error: error.message });
logger.error('HTTP', 'Worker API error (POST)', undefined, { endpoint, error: error.message });
return {
content: [{
type: 'text' as const,
+8 -6
View File
@@ -17,6 +17,8 @@ import { logger } from '../../utils/logger.js';
import { formatDate, formatTime, extractFirstFile, groupByDate } from '../../shared/timeline-formatting.js';
const COLLECTION_NAME = 'cm__claude-mem';
const RECENCY_WINDOW_DAYS = 90;
const RECENCY_WINDOW_MS = RECENCY_WINDOW_DAYS * 24 * 60 * 60 * 1000;
export class SearchManager {
constructor(
@@ -133,7 +135,7 @@ export class SearchManager {
if (chromaResults.ids.length > 0) {
// Step 2: Filter by recency (90 days)
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentMetadata = chromaResults.metadatas.map((meta, idx) => ({
id: chromaResults.ids[idx],
meta,
@@ -360,7 +362,7 @@ export class SearchManager {
logger.debug('SEARCH', 'Chroma returned semantic matches for timeline', { matchCount: chromaResults?.ids?.length ?? 0 });
if (chromaResults?.ids && chromaResults.ids.length > 0) {
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentIds = chromaResults.ids.filter((_id, idx) => {
const meta = chromaResults.metadatas[idx];
return meta && meta.created_at_epoch > ninetyDaysAgo;
@@ -912,7 +914,7 @@ export class SearchManager {
if (chromaResults.ids.length > 0) {
// Step 2: Filter by recency (90 days)
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentIds = chromaResults.ids.filter((_id, idx) => {
const meta = chromaResults.metadatas[idx];
return meta && meta.created_at_epoch > ninetyDaysAgo;
@@ -982,7 +984,7 @@ export class SearchManager {
if (chromaResults.ids.length > 0) {
// Step 2: Filter by recency (90 days)
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentIds = chromaResults.ids.filter((_id, idx) => {
const meta = chromaResults.metadatas[idx];
return meta && meta.created_at_epoch > ninetyDaysAgo;
@@ -1052,7 +1054,7 @@ export class SearchManager {
if (chromaResults.ids.length > 0) {
// Step 2: Filter by recency (90 days)
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentIds = chromaResults.ids.filter((_id, idx) => {
const meta = chromaResults.metadatas[idx];
return meta && meta.created_at_epoch > ninetyDaysAgo;
@@ -1787,7 +1789,7 @@ export class SearchManager {
if (chromaResults.ids.length > 0) {
// Filter by recency (90 days)
const ninetyDaysAgo = Date.now() - (90 * 24 * 60 * 60 * 1000);
const ninetyDaysAgo = Date.now() - RECENCY_WINDOW_MS;
const recentIds = chromaResults.ids.filter((_id, idx) => {
const meta = chromaResults.metadatas[idx];
return meta && meta.created_at_epoch > ninetyDaysAgo;