mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-03 08:03:38 +08:00
OOM fixes (applied to both feature branches): 1. trace_call_path: calloc for seen_out/seen_in dedup arrays gracefully degrades on OOM — skips dedup instead of NULL-dereference crash 2. build_snippet_response: head_tail combined buffer malloc falls back to head-only output on OOM instead of NULL snprintf Documentation (notes/ folder): - notes/token-reduction-changes.md: 8 RTK-inspired strategies, config system, real-world results, mermaid architecture diagram - notes/reference-api-indexing-changes.md: 7-layer AI grounding defense, QN prefix format, deferred work, mermaid flow diagram - notes/merged-branch-changes.md: branch lineage gitGraph, combined architecture diagram, snippet mode decision flow, token reduction pipeline per tool, test coverage, merge conflict resolution Tests: 2064 passed, 0 failed Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
128 lines
5.1 KiB
Markdown
128 lines
5.1 KiB
Markdown
# Token Reduction Changes (branch: `reduce-token-usage`)
|
|
|
|
## Overview
|
|
|
|
RTK-inspired token reduction for codebase-memory-mcp MCP tool responses. Reduces output token consumption by 72-99% depending on mode, without affecting indexing completeness. All changes are **output-side only** -- the full codebase is still indexed and stored; only query responses are trimmed.
|
|
|
|
## Changed Files
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `src/mcp/mcp.c` | 8 token reduction strategies + config-backed defaults |
|
|
| `src/cypher/cypher.c` | `CYPHER_RESULT_CEILING` 100,000 -> 10,000 |
|
|
| `src/store/store.c` | Pagination `ORDER BY name, id` for stable ordering |
|
|
| `tests/test_token_reduction.c` | 22 new tests (826 lines) |
|
|
| `tests/test_main.c` | Register `suite_token_reduction` |
|
|
| `Makefile.cbm` | Add test source |
|
|
|
|
## Commits (7)
|
|
|
|
```
|
|
5448324 mcp.c: clarify code comments for token metadata, pagination, head_tail
|
|
e9d92ed mcp.c: remove include_dependencies schema from token-reduction branch
|
|
4873697 mcp.c: fix 6 issues found in code review
|
|
83b70ed mcp: config-backed defaults + magic-number-free tool descriptions
|
|
701d8a7 Makefile.cbm, test_main.c: remove depindex refs from token-reduction branch
|
|
3518cef mcp: fix summary mode aggregation limit + add pagination hint
|
|
bb23ea4 mcp: reduce token consumption via RTK-inspired filtering strategies
|
|
```
|
|
|
|
## Strategies Implemented
|
|
|
|
### 1. Sane Default Limits (RTK: "Failure Focus")
|
|
|
|
| Tool | Parameter | Before | After | Config Key |
|
|
|------|-----------|--------|-------|------------|
|
|
| `search_graph` | `limit` | 500,000 | 50 | `search_limit` |
|
|
| `search_code` | `limit` | 500,000 | 50 | `search_limit` |
|
|
|
|
Callers can still pass explicit higher limits. Config overrides via `codebase-memory-mcp config set search_limit 200`.
|
|
|
|
### 2. Smart Truncation for `get_code_snippet` (RTK: "Structure-Only" + "Failure Focus")
|
|
|
|
Three modes via the `mode` parameter:
|
|
|
|
| Mode | Behavior | Savings |
|
|
|------|----------|---------|
|
|
| `full` (default) | Full source up to `max_lines` (default 200) | Variable |
|
|
| `signature` | Signature, params, return type only | ~99% |
|
|
| `head_tail` | First 60% + last 40% with `[... N lines omitted ...]` | ~50-70% |
|
|
|
|
The `head_tail` mode preserves function signature (head) and return/cleanup code (tail), avoiding the dangerous blind-truncation problem where return types and error handling get silently cut.
|
|
|
|
### 3. Compact Mode (RTK: "Deduplication")
|
|
|
|
`compact=true` on `search_graph` and `trace_call_path` omits the `name` field when it's a suffix of `qualified_name`, saving ~15-25% per response.
|
|
|
|
### 4. Summary Mode (RTK: "Stats Extraction")
|
|
|
|
`mode="summary"` on `search_graph` returns aggregated counts instead of individual results:
|
|
|
|
```json
|
|
{"total": 347, "by_label": {"Function": 200, "Class": 50}, "by_file_top20": {...}}
|
|
```
|
|
|
|
Savings: ~99% (1,317 bytes vs hundreds of KB).
|
|
|
|
### 5. Trace BFS Limit + Edge Case Fixes
|
|
|
|
- Default `max_results` reduced from 100 to 25 (configurable via `trace_max_results`)
|
|
- BFS cycle deduplication via `seen_ids` array
|
|
- Ambiguous function names return `candidates` array with qualified names
|
|
|
|
### 6. query_graph Output Truncation (RTK: "Tree Compression")
|
|
|
|
`max_output_bytes` parameter (default 32KB) caps raw Cypher output. Replaces with a valid JSON metadata object (not mid-JSON truncation). Does NOT change `max_rows` which would break aggregation queries.
|
|
|
|
### 7. Token Metadata (RTK: "Tracking")
|
|
|
|
Every response includes `_result_bytes` and `_est_tokens` (bytes/4 heuristic) for context cost awareness.
|
|
|
|
### 8. Pagination Hint
|
|
|
|
When `has_more=true`, responses include a `pagination_hint` field guiding how to fetch the next page.
|
|
|
|
## Architecture: Token Reduction is Output-Side Only
|
|
|
|
```mermaid
|
|
graph LR
|
|
subgraph Indexing["Indexing (unchanged)"]
|
|
A[Source Files] -->|tree-sitter parse| B[AST]
|
|
B -->|multi-pass pipeline| C[Full Graph DB]
|
|
end
|
|
subgraph Querying["Query Response (reduced)"]
|
|
C -->|SQL query| D[Full Result Set]
|
|
D -->|limit/truncate/compact/summary| E[Reduced Response]
|
|
E -->|+ _meta tokens| F[MCP Response]
|
|
end
|
|
style Indexing fill:#e8f5e9
|
|
style Querying fill:#fff3e0
|
|
```
|
|
|
|
## Config System
|
|
|
|
All defaults are runtime-configurable via `cbm_config_get_int()`:
|
|
|
|
| Config Key | Default | Controls |
|
|
|------------|---------|----------|
|
|
| `search_limit` | 50 | Default limit for search_graph/search_code |
|
|
| `snippet_max_lines` | 200 | Default max lines for get_code_snippet |
|
|
| `trace_max_results` | 25 | Default max results for trace_call_path |
|
|
| `query_max_output_bytes` | 32768 | Default byte cap for query_graph output |
|
|
|
|
## Real-World Results (RTK codebase, 45,388 symbols)
|
|
|
|
| Feature | Bytes | Savings |
|
|
|---------|-------|---------|
|
|
| Summary mode | 1,317 | 99.8% vs full |
|
|
| Compact mode | 611 vs 2,237 | 72.7% |
|
|
| Signature mode | 16 vs 2,489 | 99.4% |
|
|
| Default limit (50) | 50 results | 99.6% vs 13,818 |
|
|
|
|
## Limitations
|
|
|
|
- Summary mode caps at 10,000 results for aggregation (sufficient for most codebases)
|
|
- `max_lines=0` means unlimited, not zero lines
|
|
- `limit=0` in store.c maps to 500,000 (upstream behavior), NOT unlimited
|
|
- No tee mode (full-output recovery after truncation) -- would require file-based caching
|