feat: file-size threshold and observation dedup for timeline gate

- Skip gate for files under 1,500 bytes — timeline (~370 tokens) costs
  more than just reading small files directly
- Deduplicate observations by memory_session_id (one per session)
- Rank by specificity: files_modified > files_read, fewer tagged files > many
- Fetch 40 candidates, dedup/score down to 15 for display
- Reduce default by-file query limit from 30 to 15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-06 13:29:28 -07:00
parent 17fa383450
commit a60f79c44d
5 changed files with 281 additions and 193 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ export function getObservationsByFilePath(
options?: { projects?: string[]; limit?: number }
): ObservationRecord[] {
const likePattern = `%${filePath}%`;
const limit = options?.limit ?? 30;
const limit = options?.limit ?? 15;
const params: any[] = [likePattern, likePattern];
let projectClause = '';
@@ -116,7 +116,7 @@ export class DataRoutes extends BaseRouteHandler {
/**
* Get observations associated with a file path, scoped to projects
* GET /api/observations/by-file?path=<file_path>&projects=<comma,separated>&limit=30
* GET /api/observations/by-file?path=<file_path>&projects=<comma,separated>&limit=15
*/
private handleGetObservationsByFile = this.wrapHandler((req: Request, res: Response): void => {
const filePath = req.query.path as string | undefined;