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:
@@ -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
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user