Skip to content

feat: add Cortex entity and graph tools#35

Merged
100yenadmin merged 1 commit into
mainfrom
codex/cortex-core-entity-graph-tools
May 19, 2026
Merged

feat: add Cortex entity and graph tools#35
100yenadmin merged 1 commit into
mainfrom
codex/cortex-core-entity-graph-tools

Conversation

@100yenadmin
Copy link
Copy Markdown
Member

@100yenadmin 100yenadmin commented May 19, 2026

Summary

  • add explicit read-only Cortex entity and graph tools: cortex_entities_list, cortex_entity_detail, and cortex_graph_query
  • keep hosted owner handling server-resolved by default; the new tools expose no per-call owner_id or X-Owner-Id path
  • add manifest parity/docs/tests for the new tools and fold in char-cap logging for memory injection truncation

Issue alignment

Validation

  • npm test
  • git diff --check

Notes

  • Tools are read-only and intended for the Cortex Core Recovery smoke: remember/search/browse memory, list entity, entity detail, graph query, and Company Brain context.
  • No generic owner override is added; ownerIdMode: configured remains the existing self-host escape hatch only.

Summary by CodeRabbit

  • New Features

    • Added three new read-only entity and graph query tools for Cortex
    • Enhanced memory injection logging to display how many memories were injected versus total available, with character budget usage
  • Documentation

    • Added comprehensive documentation for Cortex core tools and owner-resolution behavior
    • Extended tools reference with details on the new entity and graph query capabilities

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 19, 2026

📝 Walkthrough

Walkthrough

This PR adds three new read-only Cortex entity and relationship graph tools to the plugin, implements memory injection truncation logging to address silent context-cap drops, extends the CortexClient with corresponding API wrappers, and validates all changes through comprehensive tests and updated documentation.

Changes

Cortex Entity/Graph Tools and Memory Truncation Logging

Layer / File(s) Summary
Entity/Graph Result Types and Formatter
src/index.ts
Defines CortexToolResult type for Cortex tool responses and exports formatCortexToolResult(label, result) to consistently format tool results into labeled human-readable strings with deterministic null/empty-result handling.
CortexClient Entity and Graph API Methods
src/index.ts
Extends CortexClient with listEntities() (supports optional entity type, search, limit, offset with clamping), getEntityDetail(entityId), and queryGraph() (supports optional center entity, max depth, max nodes with clamping) to fetch Cortex data via HTTP.
Memory Context Truncation Tracking and Logging
src/index.ts
Enhances formatMemoryContextV1 and formatMemoryContextV2 to track truncation when memories exceed maxInjectionChars, emit info logs showing injected vs. retrieved counts and char usage, and break injection early to prevent silent drops.
OpenClaw Tool Registration for Entity/Graph Access
src/index.ts
Registers cortex_entities_list, cortex_entity_detail, and cortex_graph_query as new plugin tools, each wired to the corresponding CortexClient method and formatting results via formatCortexToolResult. Updates file header comment to include new tool names.
Test Suite Extensions and New Core Tool Tests
src/__tests__/core-entity-graph-tools.test.ts, src/__tests__/memory-context-format.test.ts, src/__tests__/owner-context.test.ts, src/__tests__/plugin-manifest-parity.test.ts, package.json
Adds comprehensive test coverage including manifest registration verification, owner-resolved config validation, result formatting assertions, owner-scope checks, memory truncation logging validation, and manifest parity assertions. Updates npm test script to execute the new core-entity-graph-tools test suite.
Documentation and Plugin Manifest Updates
README.md, docs/cortex-core-tools.md, openclaw.plugin.json
Updates README tools table with three new entity/graph entries and usage guidance. Adds new docs/cortex-core-tools.md describing tool exposure, owner resolution, read-only semantics, and recommended query patterns. Registers the three new tools in the plugin manifest.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Three tools hop in—entities dance,
Graphs unwind their relational stance,
No more silent drops hide the call,
Truncation logs sing when memories fall! 🥕

🚥 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 summarizes the main change: adding three new Cortex entity and graph tools.
Linked Issues check ✅ Passed The PR implements memory injection truncation logging (issue #5) and adds Cortex entity/graph tools. Both objectives from linked issue #5 are met.
Out of Scope Changes check ✅ Passed All changes are directly related to the PR objectives: adding Cortex entity/graph tools, implementing truncation logging, and providing tests and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cortex-core-entity-graph-tools

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/index.ts`:
- Around line 1714-1718: The early return when lines.length <= 2 hides the
truncation log/footer: if truncatedByCharCap is true we should still emit the
info and append the footer before returning. Modify the block around the check
(the code using truncatedByCharCap, injectedCount, totalCount, charCount,
maxChars and the lines.push footer) so that when lines.length <= 2 you only
early-return after logging the console.info and appending the `[${injectedCount}
of ${totalCount} memories shown — use cortex_search for more]` line when
truncatedByCharCap is true (apply the same change to the other occurrence around
lines 1755-1759 / v1 and v2).
- Around line 679-687: The listEntities call is sending both page/per_page and
limit/offset which can conflict; remove the derived page and per_page entries
from the params object so only limit and offset are sent. Edit the params
construction in listEntities (the ownerParams call that currently includes page:
String(page) and per_page: String(limit)) and delete those two keys, leaving
per-page pagination to the provided limit/offset variables and the existing
limit/offset strings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ccc5b5f9-81cf-40c2-9a81-a93de42f5b74

📥 Commits

Reviewing files that changed from the base of the PR and between 9056b22 and 43a112f.

⛔ Files ignored due to path filters (15)
  • dist/__tests__/core-entity-graph-tools.test.d.ts is excluded by !**/dist/**
  • dist/__tests__/core-entity-graph-tools.test.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/core-entity-graph-tools.test.js is excluded by !**/dist/**
  • dist/__tests__/core-entity-graph-tools.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/memory-context-format.test.js is excluded by !**/dist/**
  • dist/__tests__/memory-context-format.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/owner-context.test.js is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/plugin-manifest-parity.test.js is excluded by !**/dist/**
  • dist/__tests__/plugin-manifest-parity.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/openclaw.plugin.json is excluded by !**/dist/**
📒 Files selected for processing (9)
  • README.md
  • docs/cortex-core-tools.md
  • openclaw.plugin.json
  • package.json
  • src/__tests__/core-entity-graph-tools.test.ts
  • src/__tests__/memory-context-format.test.ts
  • src/__tests__/owner-context.test.ts
  • src/__tests__/plugin-manifest-parity.test.ts
  • src/index.ts

Comment thread src/index.ts
Comment on lines +679 to +687
const limit = clampNumber(options.limit, 50, 1, 200);
const offset = clampNumber(options.offset, 0, 0, 1000000);
const page = Math.floor(offset / limit) + 1;
const params = this.ownerParams({
page: String(page),
per_page: String(limit),
limit: String(limit),
offset: String(offset),
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify which pagination contract is documented/tested in this repo.
rg -n --type=md -C2 '/api/v1/entities|entity|entities|limit|offset|page|per_page'
rg -n --type=ts -C3 'listEntities\\(|cortex_entities_list|max entities|offset|page|per_page'

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 2464


🏁 Script executed:

#!/bin/bash
# First, let's read the file to see the actual listEntities implementation
sed -n '660,700p' src/index.ts | cat -n

# Then search for any API documentation files
fd -e md -e txt | xargs grep -l "listEntities\|entities.*limit\|entities.*offset\|entities.*page" 2>/dev/null | head -20

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 1579


🏁 Script executed:

#!/bin/bash
# Search for listEntities definition and usage
rg -n "listEntities" --type=ts -B5 -A20 | head -100

# Search for test files that test listEntities
fd -e test.ts -e spec.ts | xargs grep -l "listEntities" 2>/dev/null

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 63


🏁 Script executed:

#!/bin/bash
# Look for backend API endpoint documentation or configuration
fd -e md -e json -e yaml | xargs grep -l "entities" 2>/dev/null | head -10

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 180


🏁 Script executed:

#!/bin/bash
# Read documentation files that may specify API parameters
cat docs/cortex-core-tools.md | head -100

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 1060


🏁 Script executed:

#!/bin/bash
# Search for any backend configuration or API specs
rg -n "api/v1/entities" --type=ts --type=md -B3 -A3

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Look for tests of listEntities
rg -n "listEntities" --type=ts -B2 -A10

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Search for any comment or documentation about the API parameters
rg -n "page|per_page|limit|offset" --type=md | grep -i entity

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Search more broadly for test files
fd -type f -name "*.test.*" -o -name "*.spec.*" -o -name "*test*" | head -20

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 250


🏁 Script executed:

#!/bin/bash
# Look for any usage of listEntities in the codebase
rg "listEntities" --type=ts

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Search for comments about pagination or the API endpoint
rg "page|per_page|limit|offset" --type=ts | grep -i "api\|entities\|pagina" | head -30

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 61


🏁 Script executed:

#!/bin/bash
# Check if there's any backend API spec or swagger/openapi files
fd -type f \( -name "*.openapi*" -o -name "*swagger*" -o -name "*.yaml" -o -name "*.yml" \)

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 250


🏁 Script executed:

#!/bin/bash
# List test files more simply
find . -name "*.test.ts" -o -name "*.spec.ts" -o -name "*.test.js" -o -name "*.spec.js" 2>/dev/null | head -20

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 682


🏁 Script executed:

#!/bin/bash
# Try broader search for listEntities without type restriction
rg "listEntities" -i

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 393


🏁 Script executed:

#!/bin/bash
# Search for all references to the endpoint
rg "/api/v1/entities"

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 277


🏁 Script executed:

#!/bin/bash
# Look at the actual file structure
ls -la
find . -name "*.md" | head -10

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 1062


🏁 Script executed:

#!/bin/bash
# Read the core entity graph tools test to understand pagination expectations
cat src/__tests__/core-entity-graph-tools.test.ts

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 2138


🏁 Script executed:

#!/bin/bash
# Check git history for this change
git log --oneline src/index.ts | head -10
git log -p --follow -S "page = Math.floor" -- src/index.ts | head -50

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 129


🏁 Script executed:

#!/bin/bash
# Search for any comments explaining pagination parameters
rg -n "page|per_page|limit|offset|pagina" src/index.ts | grep -E "//|/\*"

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 180


🏁 Script executed:

#!/bin/bash
# Check if there are references to external Cortex documentation
rg "cortex|github|api" README.md | grep -i api

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 353


🏁 Script executed:

#!/bin/bash
# Look at the full listEntities method with more context
sed -n '670,710p' src/index.ts | cat -n

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 1594


🏁 Script executed:

#!/bin/bash
# Final check: look at the PR or commit message for context
git log --format="%B" -1 43a112f

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 122


🏁 Script executed:

#!/bin/bash
# Check if there are any mocks or fixtures that show expected API responses
find . -name "*.json" -o -name "*.fixture" | xargs grep -l "entities\|page\|offset" 2>/dev/null | head -5

Repository: electricsheephq/evaos-cortex-plugin

Length of output: 150


Remove redundant page/per_page pagination parameters from the entities request.

The listEntities method sends both page/per_page and limit/offset parameters to /api/v1/entities. For offsets not divisible by limit, these schemes reference different slices of data. If the backend prioritizes one scheme, the result may be inconsistent with caller intent.

Since listEntities accepts limit and offset as inputs, keep those parameters and remove the derived page and per_page.

Suggested fix
   async listEntities(options: {
@@
   } = {}) {
     const limit = clampNumber(options.limit, 50, 1, 200);
     const offset = clampNumber(options.offset, 0, 0, 1000000);
-    const page = Math.floor(offset / limit) + 1;
     const params = this.ownerParams({
-      page: String(page),
-      per_page: String(limit),
       limit: String(limit),
       offset: String(offset),
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.ts` around lines 679 - 687, The listEntities call is sending both
page/per_page and limit/offset which can conflict; remove the derived page and
per_page entries from the params object so only limit and offset are sent. Edit
the params construction in listEntities (the ownerParams call that currently
includes page: String(page) and per_page: String(limit)) and delete those two
keys, leaving per-page pagination to the provided limit/offset variables and the
existing limit/offset strings.

Comment thread src/index.ts
Comment on lines 1714 to 1718
if (lines.length <= 2) return "";
if (truncatedByCharCap) {
console.info(`[cortex] memories-injected=${injectedCount}/${totalCount} chars=${charCount}/${maxChars}`);
}
lines.push(`[${injectedCount} of ${totalCount} memories shown — use cortex_search for more]`);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Char-cap truncation is still silent when zero memories fit.

If the first candidate exceeds maxChars, truncatedByCharCap becomes true but the early return "" runs before logging/footer, so truncation remains invisible.

Suggested fix (apply same pattern in v1 and v2)
-  if (lines.length <= 2) return "";
-  if (truncatedByCharCap) {
+  if (truncatedByCharCap) {
     console.info(`[cortex] memories-injected=${injectedCount}/${totalCount} chars=${charCount}/${maxChars}`);
   }
+  if (lines.length <= 2) return "";

Also applies to: 1755-1759

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/index.ts` around lines 1714 - 1718, The early return when lines.length <=
2 hides the truncation log/footer: if truncatedByCharCap is true we should still
emit the info and append the footer before returning. Modify the block around
the check (the code using truncatedByCharCap, injectedCount, totalCount,
charCount, maxChars and the lines.push footer) so that when lines.length <= 2
you only early-return after logging the console.info and appending the
`[${injectedCount} of ${totalCount} memories shown — use cortex_search for
more]` line when truncatedByCharCap is true (apply the same change to the other
occurrence around lines 1755-1759 / v1 and v2).

@100yenadmin 100yenadmin merged commit 8e42b40 into main May 19, 2026
5 checks passed
@100yenadmin 100yenadmin deleted the codex/cortex-core-entity-graph-tools branch May 19, 2026 20:51
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.

Add logging when relevant-memories injection hits maxInjectionChars cap

1 participant