Skip to content

Fix handle_before_tool dict-truthy bug + MCP response size limit - #2

Merged
PatrickNoFilter merged 4 commits into
mainfrom
fix/hook-recall-bug
Jul 10, 2026
Merged

Fix handle_before_tool dict-truthy bug + MCP response size limit#2
PatrickNoFilter merged 4 commits into
mainfrom
fix/hook-recall-bug

Conversation

@PatrickNoFilter

@PatrickNoFilter PatrickNoFilter commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

Three fixes found while diagnosing a Zero+Eling crash where search facts (via brain_recall MCP tool) caused the provider agent to crash in Zero.

Fix 1 — handle_before_tool false positive (eling-hook.py)

brain.recall() returns a dict (always truthy), so if results: was always True. The hook reported len(results) = 3 (always, because that's the number of dict keys), even when zero facts matched. Fixed to check results.get("merged", []) and report correct count.

Fix 2 — handle_after_tool double Brain init (eling-hook.py)

Created two separate Brain() instances per hook call (file edits + observations). Consolidated to a single shared instance.

Fix 3 — MCP response size limit (as_brain/mcp_server.py)

brain_recall returns the entire per_layer dict with raw results from every layer. With accumulated facts this JSON response can grow very large, causing provider context overflow and agent crash. Added a 50KB cap to the ok() serializer.


Found while debugging Zero + eling integration: https://github.com/PatrickNoFilter/eling

Summary by CodeRabbit

  • Bug Fixes
    • Large tool responses are now limited to a safe maximum size; oversized payloads are replaced with a truncation warning to prevent failures.
    • Recall output processing is more consistent, correctly handling merged recall results and avoiding empty/missing messages.
    • Tool-result and file-edit storage now reuses the same brain instance across related steps for more reliable behavior.
    • Notion integration checks are more robust when HTTP tooling isn’t available.

Three fixes for Zero integration:

1. handle_before_tool: brain.recall() returns a dict, which is ALWAYS
   truthy. Changed to check result.get('merged', []) so the hook only
   reports when there are actual recalled items. Also fixed len() to
   count merged results instead of dict keys (always 3).

2. handle_after_tool: Consolidated to create a single Brain() instance
   instead of two (one for file edits, one for tool observations).

3. as_brain MCP server: Added 50KB response size limit to ok() helper.
   Without this, brain_recall returns the full per_layer dict which can
   grow very large with accumulated facts, causing provider context
   overflow and 'provider agent crashes' in Zero.

Fixes: https://github.com/PatrickNoFilter/eling/issues
@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f10cad92-7dbb-4c3b-8b38-e92d2133367b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The MCP server truncates oversized JSON tool results. The hook reads recalled items from merged and reuses a lazily initialized Brain. Notion availability checks now treat missing httpx as unavailable instead of raising.

Changes

Runtime behavior updates

Layer / File(s) Summary
MCP response size limit
src/eling/as_brain/mcp_server.py
Serialized tool results over 50,000 characters now return a truncation warning payload.
Hook recall and Brain reuse
src/eling/zero_plugin/eling-hook.py
Recall messages use the merged results list, while after-tool persistence shares a lazily initialized Brain instance.
Notion httpx availability handling
src/eling/layers/notion.py
Availability checks catch missing-httpx errors and mark the Notion client as unavailable.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes two of the main changes: the handle_before_tool bug fix and the MCP response size cap.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/hook-recall-bug

Comment @coderabbitai help to get the list of available commands.

notion.available property and _has_httpx() both called _require_httpx()
which raises RuntimeError when httpx is not installed.

Default recall layers now include 'notion' (main branch changed from
['builtin', 'facts', 'kb', 'code'] to include 'notion'). This means
any call to brain.recall() without explicit layers triggers
notion.available, which crashed the benchmark job when httpx is absent.

Fix: wrap _require_httpx() in try/except so available=property returns
False instead of raising. Same fix for _has_httpx().

Fixes benchmark CI failure for PR #2.
The try/except around _require_httpx() assigns _HAS_HTTPX, but without
a 'global' declaration Python treats it as a local variable, causing
UnboundLocalError. Add global declarations to available and _has_httpx.
The 'Comment benchmark on PR' step uses GITHUB_TOKEN to call
issues.createComment, which requires pull-requests: write scope.
Without it, runs fail with 'HttpError: Resource not accessible by
integration'.
@github-actions

Copy link
Copy Markdown

⏱ Eling Benchmark

Operation p50 (ms) p95 (ms) avg (ms)
facts.remember 0.03 0.03 0.03
facts.search 1.43 2.85 1.52
kb.remember 0.02 0.03 0.03
kb.search 0.38 0.40 0.38
code.search 0.07 0.11 0.08
stats 0.26 0.28 0.26
think 1.70 1.70 1.63
export 9.20 9.29 9.22
reason 1.41 6.04 1.91

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Caution

Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted.

Error details
putComment timed out

@PatrickNoFilter

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@PatrickNoFilter
PatrickNoFilter merged commit fb0ecd7 into main Jul 10, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant