Skip to content

feat(agent_memory): add memory retrieval domain with smart walk parser fix - #3421

Merged
senamakel merged 13 commits into
tinyhumansai:mainfrom
senamakel:feat/agent-memory-domain
Jun 6, 2026
Merged

senamakel merged 13 commits into
tinyhumansai:mainfrom
senamakel:feat/agent-memory-domain

Conversation

@senamakel

@senamakel senamakel commented Jun 6, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Add agent_memory domain with call_memory_agent orchestrator tool for delegated memory retrieval
  • Move memory_loader.rs from agent/ into the new domain following canonical module shape
  • Fix smart walk tool-call parser to handle both JSON and XML-style LLM outputs
  • Replace memory_recall/memory_tree/query_memory with call_memory_agent across all 9 agents
  • Add comprehensive e2e tests with mock LLM responses covering multi-turn walks, cross-content-type retrieval, and edge cases

Problem

  • Memory retrieval logic (memory_loader.rs) lived in the generic agent/ directory with no dedicated domain boundary
  • The smart walk's tool-call parser only accepted JSON format ({"name":"...","arguments":{...}}), but chat-tier LLMs sometimes emit XML-style calls (<tool_name>...</tool_name><parameters>...</parameters>). These were silently dropped, causing the walk to exit after one turn with no evidence.
  • No orchestrator-level tool existed to delegate memory queries to the memory agent
  • Each agent carried its own set of low-level memory tools instead of delegating through the memory agent

Solution

  • Created src/openhuman/agent_memory/ domain with mod.rs, types.rs, ops.rs, tools.rs, memory_loader.rs, and embedded agent definition (agent/agent.toml + prompt.md)
  • Added parse_single_tool_call() with JSON-first + XML fallback parsing, and extract_xml_tag() helper
  • Updated smart walk system prompt with explicit JSON format example to nudge the primary path
  • Added call_memory_agent tool to the orchestrator's tool surface for delegated memory retrieval
  • Replaced memory_recall/memory_tree/query_memory with call_memory_agent in all 9 agents (orchestrator, planner, researcher, help, presentation_agent, profile_memory_agent, crypto_agent, markets_agent, trigger_reactor)
  • Added benchmark scripts (scripts/bench-memory-retrieval.sh, scripts/bench-memory-walk.sh)

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — 14 new tests: 8 parser unit tests (JSON, XML, mixed, garbage), 6 e2e walk tests (multi-turn, cross-content-type, LLM-gives-up, direct-answer, evidence collection)
  • N/A: Diff coverage gate — Rust-only changes; will rely on CI cargo-llvm-cov run
  • N/A: Coverage matrix updated — new domain, no existing matrix rows to update
  • N/A: All affected feature IDs from the matrix are listed — new domain not yet in matrix
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • N/A: Manual smoke checklist updated — internal agent plumbing, no release-cut surface
  • N/A: Linked issue closed — no linked issue

Impact

  • Desktop: memory retrieval via orchestrator now works reliably regardless of LLM tool-call format
  • Performance: no regression; parser fallback adds ~us per tool call
  • Compatibility: backward-compatible; JSON format still primary, XML is fallback only

Related

  • Follow-up PR(s)/TODOs: standalone core keychain path resolution for external debugging

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/agent-memory-domain
  • Commit SHA: 973c464

Validation Run

  • pnpm --filter openhuman-app format:check
  • N/A: pnpm typecheck — Rust-only changes
  • Focused tests: cargo test smart_walk — 19 passed, 6 ignored (staging-only)
  • Rust fmt/check (if changed): cargo fmt applied and verified
  • N/A: Tauri fmt/check (if changed) — no Tauri changes

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Smart walk now parses XML-style tool calls from chat-tier LLMs instead of silently dropping them; all agents delegate memory retrieval through call_memory_agent
  • User-visible effect: Memory queries that previously returned empty/truncated answers now complete their full retrieval pipeline

Parity Contract

  • Legacy behavior preserved: JSON tool-call format remains primary; XML is additive fallback
  • Guard/fallback/dispatch parity checks: N/A

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: This PR
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • New Features

    • Introduced Memory Agent, a dedicated agent for memory retrieval that centralizes memory access across the platform
    • Added memory operation benchmarking capabilities
  • Improvements

    • Enhanced memory query parsing for improved tool call handling
    • Unified memory tool access through a single agent interface across multiple agents

senamakel added 7 commits June 5, 2026 19:36
New top-level domain `src/openhuman/agent_memory/` housing the memory
retrieval agent, benchmark harness, and performance tracking types.

- agent_memory domain: mod.rs, types.rs (WalkBenchmark, BenchmarkSummary),
  ops.rs (bench_walk, bench_batch wrapping run_smart_walk with timing)
- Built-in agent_memory agent: worker tier, read-only sandbox, tools
  limited to memory_tree/recall/walk/smart_walk/doctor/query_memory
- Prompt focused on retrieval strategy, performance contract, and
  citation-based output format
- scripts/bench-memory-walk.sh: CLI benchmark runner against a live
  memory tree, JSONL output to target/bench-memory/
Move the canonical `memory_loader.rs` (MemoryLoader trait,
DefaultMemoryLoader, MemoryCitation, cross-chat context, prior
conversations) from `agent/memory_loader.rs` into the new
`agent_memory/memory_loader.rs` domain module.

The original file becomes a thin re-export shim so all existing
harness imports (`agent::memory_loader::*`) continue to resolve.
…o domain

- New `call_memory_agent` tool: spawns the agent_memory sub-agent to
  autonomously walk the memory tree and return cited context for a
  query. Supports sync (blocking) and async (fire-and-forget) modes.
- Move agent definition from agent_registry/agents/agent_memory/ into
  agent_memory/agent/ so the domain owns its own agent definition.
- Switch model hint from "agentic" to "chat" (lightweight/fast tier).
- Register call_memory_agent in orchestrator's direct tool list.
- Register tool in the global tool registry (tools/ops.rs + mod.rs).
The chat-tier LLM sometimes emits <tool_name>/<parameters> XML inside
<tool_call> blocks instead of the expected JSON {"name","arguments"}
format. The JSON-only parser silently dropped these, causing the walk
to exit after one turn with no evidence.

- Add parse_single_tool_call() with JSON-first + XML fallback parsing
- Add extract_xml_tag() helper for the XML path
- Update system prompt with explicit JSON format example to nudge the
  model toward the primary path
- Add bench-memory-retrieval.sh script for local benchmarking
Covers the XML tool-call parsing fix and multi-source memory walking:

Parser unit tests:
- XML-style <tool_name>/<parameters> inside <tool_call> blocks
- Mixed JSON + XML format in same response
- XML params with no <parameters> tag
- extract_xml_tag helper
- parse_single_tool_call JSON/XML/garbage paths

E2E walk tests (StubProvider, seeded content tree):
- walk_synced_email_with_keyword_and_evidence: 4-turn walk across
  email + docs, verifies evidence from both sources
- walk_with_xml_format_tool_calls: the actual bug scenario — XML
  calls are parsed, not silently dropped
- walk_reads_across_content_types: evidence from raw/episodic/wiki
- walk_llm_gives_up_uses_fallback: empty response → LlmGaveUp
- walk_direct_answer_without_tools: no tool calls → direct answer
- walk_collect_evidence_deduplicates_within_limit: multi-batch
  evidence collection
@senamakel
senamakel requested a review from a team June 6, 2026 02:14
@coderabbitai

coderabbitai Bot commented Jun 6, 2026 •

Copy link
Copy Markdown
Contributor

Need the big picture first? Review this PR in Change Stack to see what changed before going file by file.

Review Change Stack

Warning

Review limit reached

@senamakel, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 19 minutes and 22 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 62d0255c-c160-4ed9-81f1-b51782a79f25

📥 Commits

Reviewing files that changed from the base of the PR and between df4b3d0 and de47126.

📒 Files selected for processing (4)
  • scripts/bench-memory-retrieval.sh
  • src/openhuman/agent_memory/tools.rs
  • src/openhuman/mcp_server/resources.rs
  • tests/orchestrator_presentation_wiring.rs
📝 Walkthrough

Walkthrough

This PR introduces a new memory agent subsystem for OpenHuman that consolidates memory retrieval operations into a dedicated agent (agent_memory), replaces direct memory tool usage across agents with a call_memory_agent tool, enhances smart-walk tool-call parsing to support JSON with XML fallback, and adds comprehensive benchmarking infrastructure for memory retrieval performance evaluation.

Changes

Memory Agent Feature

Layer / File(s) Summary
Module structure and re-exports
src/openhuman/mod.rs, src/openhuman/agent/memory_loader.rs, src/openhuman/tools/mod.rs, src/openhuman/agent_memory/mod.rs
New agent_memory module entry point and facade re-export from agent_memory::memory_loader; tools module re-exports agent_memory tools; old memory_loader.rs becomes forwarding layer.
Memory context loader trait and implementation
src/openhuman/agent_memory/memory_loader.rs, tests/...
MemoryLoader async trait and DefaultMemoryLoader construct prompt context from working memory (semantic recall), prior conversations (conversation namespace), and cross-chat (JSONL or fallback). MemoryCitation and collect_recall_citations provide semantic matches with relevance filtering. Comprehensive tests verify date stamping, filtering, truncation, and cross-chat provenance rendering.
Agent definition, prompt, and documentation
src/openhuman/agent_memory/agent/agent.toml, src/openhuman/agent_memory/agent/prompt.md, src/openhuman/agent_memory/agent/prompt.rs, src/openhuman/agent_memory/README.md
Memory Agent TOML with read-only sandbox mode and tool allowlist; markdown prompt defining retrieval strategy and output format (inline citations + sources); dynamic prompt builder composing archetype with user files and tools sections; README documenting module layout and tool surface.
Benchmarking types and operations
src/openhuman/agent_memory/types.rs, src/openhuman/agent_memory/ops.rs
RetrievalStep, WalkBenchmark, BenchmarkSummary track per-step and aggregate performance. bench_walk measures single-query smart-walk latency; bench_batch runs multiple queries and aggregates p50/p95 percentiles and averages. Unit tests verify empty and single-benchmark cases.
CallMemoryAgentTool implementation
src/openhuman/agent_memory/tools.rs, src/openhuman/tools/ops.rs
Tool with JSON schema for query, optional context/max_turns/async mode. Validates parent agent context, loads agent registry, runs sub-agent with optional background spawning or inline awaiting. Async mode returns task ID; sync mode returns result with elapsed time and clarification if requested. Registered in tool runtime inventory.
Built-in agent registration and test updates
src/openhuman/agent_registry/agents/loader.rs
agent_memory added to BUILTINS with TOML and dynamic prompt builder. Loader tests updated to require call_memory_agent tool for trigger_reactor, orchestrator, presentation_agent, help, crypto_agent, markets_agent.
Agent TOML tool allowlist updates
src/openhuman/agent_registry/agents/{crypto_agent,help,markets_agent,orchestrator,planner,presentation_agent,profile_memory_agent,researcher,trigger_reactor}/agent.toml
Nine agent configs updated: memory_recall/memory_tree/query_memory replaced with call_memory_agent; other tools unchanged; comments updated to reflect memory delegation.
Bash benchmarking scripts
scripts/bench-memory-retrieval.sh, scripts/bench-memory-walk.sh
Two standalone benchmarks: retrieval validates binary, discovers content root, runs memory query/grep/RPC benchmarks; walk script runs smart-walk queries via RPC, times each, logs JSONL results with status (OK/FAIL), prints summary (pass/fail/total time) and exits with status 1 if any failed.

Smart Walk Tool Call Parsing

Layer / File(s) Summary
JSON tool calls with XML fallback parsing
src/openhuman/memory/query/smart_walk.rs
System prompt updated to specify <tool_call> JSON payloads. parse_tool_calls now delegates to new parse_single_tool_call (JSON-first with XML fallback). XML fallback extracts <tool_name> and <parameters>, attempts JSON parse, and heuristically converts XML-like tags to JSON arguments via extract_xml_tag if needed.
Tool parsing and end-to-end walk tests
src/openhuman/memory/query/smart_walk.rs, tests/...
Expands tests with XML-format parser unit coverage (basic XML, JSON params, mixed sequences, missing params) and multiple seeded run_smart_walk E2E scenarios (XML-emitting providers, cross-content-type reads, direct answers, empty-response fallback, multi-turn evidence with deduplication).
End-to-end test updates
tests/agent_retrieval_e2e.rs
Updates orchestrator_lists_memory_tree_tools to verify call_memory_agent presence in orchestrator TOML and confirm old memory_tree_* names are superseded; error message updated accordingly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Poem

🐰 A memory agent born, context flows anew,
JSON tool calls dance, with XML backup too,
Smart walks now benchmark their retrieval grace,
Cross-chat and working memory find their place!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: adding a new memory retrieval domain with an important parser fix, accurately reflecting the core objectives.
Docstring Coverage ✅ Passed Docstring coverage is 91.95% which is sufficient. The required threshold is 80.00%.
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.

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


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

@coderabbitai coderabbitai Bot added feature Net-new user-facing capability or product behavior. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. labels Jun 6, 2026
… call_memory_agent

All 9 agents that had direct memory tool access now delegate through
call_memory_agent instead. This consolidates memory retrieval behind
the memory agent, which internally uses the full tool suite (smart
walk, keyword search, entity search, tree browse, etc.).

Agents updated: orchestrator, planner, researcher, help,
presentation_agent, profile_memory_agent, crypto_agent,
markets_agent, trigger_reactor.

profile_memory_agent retains memory_doctor (diagnostics) and
memory_store/memory_forget (write ops) since those are not retrieval.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 18

🧹 Nitpick comments (1)
src/openhuman/agent_memory/agent/prompt.md (1)

32-38: 💤 Low value

Add language specifier to fenced code block.

The fenced code block at lines 32-38 lacks a language specifier. For clarity and to satisfy linting tools, specify the language (e.g., text or markdown) after the opening backticks.

📝 Proposed fix
-```
+```text
 [Answer text with citations like [1], [2]...]
 
 Sources:
🤖 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/openhuman/agent_memory/agent/prompt.md` around lines 32 - 38, The fenced
code block in src/openhuman/agent_memory/agent/prompt.md (the snippet starting
with ``` and the block showing "Answer text with citations..." and "Sources:")
is missing a language specifier; update the opening fence to include a language
token (for example change ``` to ```text or ```markdown) so the block is
explicitly typed, which satisfies linters and improves rendering.

Source: Linters/SAST tools

🤖 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 `@scripts/bench-memory-retrieval.sh`:
- Line 26: The script currently hardcodes CONTENT_ROOT to a single user path;
change CONTENT_ROOT to be set from an environment variable or a positional/flag
argument (e.g., check $CONTENT_ROOT or parse a --content-root/first-arg) and
fall back to a sensible default only if not provided; then validate the
directory exists before proceeding (exit with a clear error if test -d
"$CONTENT_ROOT" fails). Update references to the CONTENT_ROOT variable in the
script so the rest of the benchmark uses the provided path (look for the
CONTENT_ROOT assignment and any usages in bench-memory-retrieval.sh).
- Around line 158-160: The Python one-liner used to set HITS consumes stdin
twice (sys.stdin.read() in both the condition and branch), causing the second
read to be empty; update the HITS assignment to read stdin once into a local
variable (e.g., s = sys.stdin.read()) and then use that variable for the '{'
check and json.loads(...) when extracting result.total, or alternatively replace
the one-liner with a jq-based extraction; ensure the command still falls back to
"parse-error" on failure and that the variable name HITS remains the target of
the assignment.

In `@scripts/bench-memory-walk.sh`:
- Line 163: The echo writes an unescaped "$query" into JSONL causing injection;
change this to build the JSON safely with a JSON serializer (e.g., jq) instead
of string interpolation: use jq -n with --arg for "$query" and "$STATUS" and
--argjson for "$ELAPSED_MS" and include the timestamp via date -u, then append
that safe JSON to "$RESULTS_FILE". Update the line that references
RESULTS_FILE/query/ELAPSED_MS/STATUS to use this jq-based construction so the
query is properly escaped.
- Around line 127-139: The RPC payload currently interpolates the query directly
into the here-doc (RPC_PAYLOAD) causing JSON injection when query contains
quotes/newlines; replace the raw here-doc with a safe JSON builder (e.g., use jq
-n) that sets fields with --arg/--argjson so query, NAMESPACE, MAX_TURNS and the
id ("bench-$idx") are passed as arguments instead of string interpolation;
update the code that assigns RPC_PAYLOAD to use jq (or another proper JSON
serializer) with --arg query "$query", --arg namespace "$NAMESPACE", --arg id
"bench-$idx" and --argjson max_turns "$MAX_TURNS" so the JSON is correctly
escaped and robust.

In `@src/openhuman/agent_memory/agent/agent.toml`:
- Around line 1-28: Add an entry to AGENTS.md documenting the new agent with id
"agent_memory" / display_name "Memory Agent": describe its purpose (memory
retrieval and tree-walking specialist), the when_to_use guidance (copy the
when_to_use text), key config items (delegate_name: retrieve_memory, model hint:
"chat", sandbox_mode: "read_only", agent_tier: "worker", temperature: 0.2,
max_iterations: 15) and list the available tools (memory_recall, memory_tree,
memory_tree_walk, memory_smart_walk, query_memory, memory_doctor,
ask_user_clarification), and include a short example of intended usage and any
important omit_* flags (omit_identity=true, omit_memory_context=false,
omit_safety_preamble=true, omit_skills_catalog=true, omit_profile=false,
omit_memory_md=false).

In `@src/openhuman/agent_memory/memory_loader.rs`:
- Around line 200-207: The current memory.recall(...) calls (e.g., the one that
assigns working_entries) use unwrap_or_default(), which silently drops errors;
update each such call (including the other recall usages that set recent_entries
and longterm_entries) to handle the Result by logging the error with a stable,
grep-friendly prefix (e.g., "MEMORY_RECALL_FAILURE") and relevant context
(query, limit, and backend id) before falling back to an empty vector; keep the
fallback behavior but replace unwrap_or_default() with explicit match/if let
that logs at debug/error level and returns Vec::new() on Err.

In `@src/openhuman/agent_memory/mod.rs`:
- Line 12: Change the exported module from the singular "tool" to the plural
"tools" to match the project contract: replace the `pub mod tool;` export with
`pub mod tools;` and rename the corresponding file from tool.rs to tools.rs (or
create tools.rs if missing), moving any content into tools.rs and updating any
downstream re-exports or uses that reference `openhuman::agent_memory::tool` to
`openhuman::agent_memory::tools`.

In `@src/openhuman/agent_memory/ops.rs`:
- Around line 110-134: The bench_batch loop currently logs per-query failures
but still returns Ok((results, summary)), allowing a completely failed batch to
be treated as success; update bench_batch so that after computing results and
summary it checks if queries is non-empty and results.is_empty() and in that
case returns an Err (e.g., using anyhow::anyhow or converting a descriptive
error) instead of Ok; keep existing behavior when queries is empty or some
results succeeded, and reference the bench_batch function, the results and
queries variables, bench_walk calls, and BenchmarkSummary::from_benchmarks to
locate where to add the check and error return.
- Around line 27-33: The log statements in src/openhuman/agent_memory/ops.rs
(the log::info calls that include the `query` variable in agent_memory::bench
and the other occurrences around the referenced ranges) currently emit raw user
text; replace them with a redacted representation (e.g., compute a stable hash
such as SHA-256 of `query` plus the character length) and log only that
hash+length string instead of the raw `query`. Update every logging site that
references `query` (the log::info calls shown and the ones at the other noted
ranges) to use the redaction helper instead of printing the raw value, ensuring
no raw query or PII is written to logs.

In `@src/openhuman/agent_memory/README.md`:
- Around line 28-43: The fenced code block in README.md (the directory tree
block starting at the shown snippet) is missing a language tag; update the
opening triple-backticks to include a language (for example use ```text) so the
block satisfies MD040 and the docs linter; ensure only the opening fence is
changed (e.g., ``` -> ```text) and no other content is modified.
- Around line 62-65: The README references the wrong registration path for the
built-in agent; update the doc to state that the built-in agent_memory is wired
from the agent's agent.toml (symbol: agent/agent.toml) used by the built-in
loader, and adjust the file list so prompt.rs and prompt.md are described as
living alongside that agent manifest (symbols: prompt.rs, prompt.md,
agent_memory, agent/agent.toml) rather than under the incorrect agent_registry
path. Ensure the single-line entry and bullet list reflect the corrected
location and filenames.

In `@src/openhuman/agent_memory/tool.rs`:
- Around line 65-70: The schema exposes "max_turns" but the execution path never
reads it; update the code that constructs SubagentRunOptions so it reads the
provided "max_turns" parameter (validate against 1..20 per schema) and assigns
it to the corresponding field on SubagentRunOptions instead of relying on
defaults; specifically locate where SubagentRunOptions is built (the code that
sets task_id around the current construction) and add parsing/validation of the
"max_turns" input, clamping/failing if out of range, then pass that value into
SubagentRunOptions so the declared schema is actually enforced at runtime.
- Around line 137-142: The current log in call_memory_agent prints the raw query
at info level; remove or stop logging the full `query` value and instead log
only non-sensitive correlation metadata (e.g., `task_id`, `is_async`) and a safe
diagnostic such as `query.len()` or a redacted snippet; also lower the level to
debug/trace (use log::debug! or log::trace!) for diagnostics. Locate the
log::info! call in the `call_memory_agent` context and replace it so it does not
include `query` (use `query.len()` or a fixed placeholder) and move it to
debug/trace level to avoid exposing PII in production logs. Ensure any remaining
logs follow the guideline to never print full user-provided content.

In `@src/openhuman/agent_memory/types.rs`:
- Around line 45-84: The BenchmarkSummary::from_benchmarks function (which
consumes &[WalkBenchmark] and computes stats) is business logic and should be
moved out of the domain types module into the ops/stats helper module; extract
the entire function body into a new function in ops.rs (or a new stats helper)
and keep BenchmarkSummary as a pure Serde/type definition, then update
references to call the new function, export it if needed, and adjust
imports/visibility for BenchmarkSummary, WalkBenchmark, and the new
from_benchmarks implementation so compilation and access remain correct.
- Around line 67-74: The percentile indexing currently truncates with `as usize`
which biases p50/p95 for even or exact-rank sample sizes; update the computation
around `p50_idx`, `p95_idx` and the assignments to
`p50_elapsed_ms`/`p95_elapsed_ms` to use a proper percentile calculation (e.g.,
compute a float index via (benchmarks.len() - 1) as f64 * quantile and either
round or perform linear interpolation between the two neighboring `elapsed_ms`
values) instead of simple truncation, ensuring you handle small lengths and
clamp indices safely while still setting `runs` and `avg_elapsed_ms` as before.

In `@src/openhuman/memory/query/smart_walk.rs`:
- Around line 1279-1338: Add verbose debug logging in parse_single_tool_call and
extract_xml_tag: log when entering parse_single_tool_call and the input snippet,
log JSON parse failures (including serde error) with a stable prefix like
"[memory::parse]" and a correlation id if available, log selection of the XML
fallback branch ("[memory::parse] using XML-fallback"), log success/failure of
parsing parameters (whether parsed_args came from JSON or heuristic XML parsing)
and any skipped/malformed tags, and log when returning None (dropped call) with
reason; also emit trace-level entry/exit logs from extract_xml_tag when tags are
found/missing using the same prefix. Include function names
parse_single_tool_call and extract_xml_tag in the messages for easy grep.
- Around line 1146-1147: The system-prompt example contains a stray double-quote
at the end of the raw string literal (`</tool_call>"#`) which corrupts the
example; locate the example that contains the tool_call entries `list_sources`
and `keyword_search` and remove the extra `"` so the ending is `</tool_call>#`
(i.e., the raw string delimiter should not be preceded by an extra quote),
ensuring the example string is a valid Rust raw string.

---

Nitpick comments:
In `@src/openhuman/agent_memory/agent/prompt.md`:
- Around line 32-38: The fenced code block in
src/openhuman/agent_memory/agent/prompt.md (the snippet starting with ``` and
the block showing "Answer text with citations..." and "Sources:") is missing a
language specifier; update the opening fence to include a language token (for
example change ``` to ```text or ```markdown) so the block is explicitly typed,
which satisfies linters and improves rendering.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e406ba3c-32c4-4776-acc6-ecd314ea5770

📥 Commits

Reviewing files that changed from the base of the PR and between 8b0bf9d and 622e636.

📒 Files selected for processing (19)
  • scripts/bench-memory-retrieval.sh
  • scripts/bench-memory-walk.sh
  • src/openhuman/agent/memory_loader.rs
  • src/openhuman/agent_memory/README.md
  • src/openhuman/agent_memory/agent/agent.toml
  • src/openhuman/agent_memory/agent/mod.rs
  • src/openhuman/agent_memory/agent/prompt.md
  • src/openhuman/agent_memory/agent/prompt.rs
  • src/openhuman/agent_memory/memory_loader.rs
  • src/openhuman/agent_memory/mod.rs
  • src/openhuman/agent_memory/ops.rs
  • src/openhuman/agent_memory/tool.rs
  • src/openhuman/agent_memory/types.rs
  • src/openhuman/agent_registry/agents/loader.rs
  • src/openhuman/agent_registry/agents/orchestrator/agent.toml
  • src/openhuman/memory/query/smart_walk.rs
  • src/openhuman/mod.rs
  • src/openhuman/tools/mod.rs
  • src/openhuman/tools/ops.rs

Comment thread scripts/bench-memory-retrieval.sh Outdated
Comment thread scripts/bench-memory-retrieval.sh
Comment thread scripts/bench-memory-walk.sh Outdated
Comment thread scripts/bench-memory-walk.sh Outdated
Comment thread src/openhuman/agent_memory/agent/agent.toml
Comment thread src/openhuman/agent_memory/types.rs
Comment thread src/openhuman/agent_memory/types.rs Outdated
Comment thread src/openhuman/memory/query/smart_walk.rs Outdated
Comment thread src/openhuman/memory/query/smart_walk.rs
Comment thread src/openhuman/memory/query/smart_walk.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/openhuman/agent_registry/agents/loader.rs (1)

192-195: ⚡ Quick win

Update loader module docs to match the new built-in layout.

BUILTINS now includes agent_memory from ../../agent_memory/agent/agent.toml, but the file header still says every built-in lives in this folder with only local agent.toml/prompt.rs. Please update that guidance so future edits don’t follow stale assumptions.

Based on learnings: “New or changed behavior must ship with matching documentation—at minimum add concise rustdoc / code comments where flow is not obvious, and update AGENTS.md, architecture docs, or feature docs when repository rules or user-visible behavior change.”

🤖 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/openhuman/agent_registry/agents/loader.rs` around lines 192 - 195, The
loader module's documentation is stale because BUILTINS now includes entries
that reference agents outside the local folder (e.g., the new "agent_memory"
entry pointing at "../../agent_memory/agent/agent.toml"); update the
rustdoc/comments in src/openhuman/agent_registry/agents/loader.rs to explain the
new built-in layout and that BUILTINS entries may point to external agent dirs,
and also update or add a short note in AGENTS.md (or relevant
architecture/feature docs) reflecting the rule that built-ins can live in
sibling crates and must provide agent.toml and prompt builder functions
(reference BUILTINS and the "agent_memory" entry and prompt_fn build function)
so future contributors do not assume only local agent.toml/prompt.rs files are
allowed.

Source: Learnings

🤖 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.

Nitpick comments:
In `@src/openhuman/agent_registry/agents/loader.rs`:
- Around line 192-195: The loader module's documentation is stale because
BUILTINS now includes entries that reference agents outside the local folder
(e.g., the new "agent_memory" entry pointing at
"../../agent_memory/agent/agent.toml"); update the rustdoc/comments in
src/openhuman/agent_registry/agents/loader.rs to explain the new built-in layout
and that BUILTINS entries may point to external agent dirs, and also update or
add a short note in AGENTS.md (or relevant architecture/feature docs) reflecting
the rule that built-ins can live in sibling crates and must provide agent.toml
and prompt builder functions (reference BUILTINS and the "agent_memory" entry
and prompt_fn build function) so future contributors do not assume only local
agent.toml/prompt.rs files are allowed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2ffaeea7-c350-4482-9d2f-0b492a36b18a

📥 Commits

Reviewing files that changed from the base of the PR and between 622e636 and 973c464.

📒 Files selected for processing (10)
  • src/openhuman/agent_registry/agents/crypto_agent/agent.toml
  • src/openhuman/agent_registry/agents/help/agent.toml
  • src/openhuman/agent_registry/agents/loader.rs
  • src/openhuman/agent_registry/agents/markets_agent/agent.toml
  • src/openhuman/agent_registry/agents/orchestrator/agent.toml
  • src/openhuman/agent_registry/agents/planner/agent.toml
  • src/openhuman/agent_registry/agents/presentation_agent/agent.toml
  • src/openhuman/agent_registry/agents/profile_memory_agent/agent.toml
  • src/openhuman/agent_registry/agents/researcher/agent.toml
  • src/openhuman/agent_registry/agents/trigger_reactor/agent.toml
💤 Files with no reviewable changes (1)
  • src/openhuman/agent_registry/agents/orchestrator/agent.toml

- Rename tool.rs → tools.rs for canonical module shape consistency
- Fix hardcoded user path in bench-memory-retrieval.sh (auto-detect)
- Fix stdin double-read in bench-memory-retrieval.sh Python one-liner
- Fix JSON injection in bench-memory-walk.sh via python3 json.dumps
- Redact raw queries from log lines (ops.rs, tools.rs)
- Return Err when all benchmark queries fail (ops.rs)
- Wire max_turns through to subagent prompt (tools.rs)
- Fix percentile indexing off-by-one (types.rs)
- Add debug logging to XML parser fallback (smart_walk.rs)
- Fix stray quote in system prompt example (smart_walk.rs)
- Add actual duplicate to dedup test (smart_walk.rs)
- Fix README code block language and registration path
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
senamakel added 2 commits June 5, 2026 22:36
…y_agent

The e2e test asserted memory_tree was in orchestrator tools — updated to
check for call_memory_agent instead, matching the agent TOML migration.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
scripts/bench-memory-retrieval.sh (1)

165-171: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

HITS parsing remains fragile and misses valid RPC response shapes.

Line 169 parses only the last line containing {, which is usually not a complete JSON document for pretty output. It also only checks result.total, but CLI output can be bare total when logs are empty.

Suggested patch
-    HITS=$(echo "$OUTPUT" | python3 -c "
+    HITS=$(printf '%s' "$OUTPUT" | python3 -c "
 import sys,json
-raw = sys.stdin.read()
-last_line = [l for l in raw.split('\n') if '{' in l]
-d = json.loads(last_line[-1]) if last_line else {}
-print(d.get('result',{}).get('total',0))
+raw = sys.stdin.read().strip()
+obj = None
+
+# Try full output first.
+try:
+    obj = json.loads(raw)
+except Exception:
+    # Fallback: parse trailing JSON block if non-JSON text precedes it.
+    starts = [i for i, ch in enumerate(raw) if ch == '{']
+    for i in reversed(starts):
+        try:
+            obj = json.loads(raw[i:])
+            break
+        except Exception:
+            pass
+
+if not isinstance(obj, dict):
+    print('parse-error')
+else:
+    payload = obj.get('result', obj)
+    print(payload.get('total', 0) if isinstance(payload, dict) else 0)
 " 2>/dev/null || echo "parse-error")
🤖 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 `@scripts/bench-memory-retrieval.sh` around lines 165 - 171, The HITS
assignment parsing is fragile—update the shell snippet that sets HITS to
robustly extract the last complete JSON object from OUTPUT (not just the last
line containing "{"), parse it, and read total from either result.total or
top-level total (falling back to 0 or a parse-error). Locate the HITS assignment
and replace the Python parsing logic (the inline python block) so it finds the
final balanced JSON object (e.g., scan from the last '{' and match braces or
extract JSON blocks), json.loads that object, then compute hits =
d.get('result', {}).get('total') or d.get('total', 0) and print that; ensure
non-JSON or parse failures still return "parse-error" as before.
🤖 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 `@scripts/bench-memory-retrieval.sh`:
- Around line 26-32: The pipeline computing CONTENT_ROOT can fail early under
set -euo pipefail when "$WORKSPACE_DIR/users" is missing; before running the
find that sets CONTENT_ROOT, explicitly check that the directory
"$WORKSPACE_DIR/users" exists (guard the path) and emit the same error/exit if
it does not, or alternatively make the find pipeline non-fatal (e.g., ensure it
cannot return a non-zero status) so the subsequent if [[ -z "$CONTENT_ROOT" ]]
check (which references CONTENT_ROOT) still executes; update the logic around
WORKSPACE_DIR and the CONTENT_ROOT assignment to include this guard.

In `@src/openhuman/agent_memory/tools.rs`:
- Around line 103-107: The code builds max_turns from args.get("max_turns") and
currently allows 0 because it only applies an upper bound via .min(20); change
the parsing to clamp into the valid range [1,20] (e.g., map the value to
v.max(1).min(20) as usize or otherwise enforce a minimum of 1) so the schema
minimum is respected and the later message that references max_turns can't
report "use at most 0 retrieval turns"; apply the same fix to the other
identical extraction (the second args.get("max_turns") / map(|v| v.min(20) as
usize) occurrence) and ensure any error/message logic uses the new clamped
value.

---

Duplicate comments:
In `@scripts/bench-memory-retrieval.sh`:
- Around line 165-171: The HITS assignment parsing is fragile—update the shell
snippet that sets HITS to robustly extract the last complete JSON object from
OUTPUT (not just the last line containing "{"), parse it, and read total from
either result.total or top-level total (falling back to 0 or a parse-error).
Locate the HITS assignment and replace the Python parsing logic (the inline
python block) so it finds the final balanced JSON object (e.g., scan from the
last '{' and match braces or extract JSON blocks), json.loads that object, then
compute hits = d.get('result', {}).get('total') or d.get('total', 0) and print
that; ensure non-JSON or parse failures still return "parse-error" as before.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e1000733-879f-4e1c-99ca-0c00964a68bc

📥 Commits

Reviewing files that changed from the base of the PR and between 973c464 and df4b3d0.

📒 Files selected for processing (10)
  • scripts/bench-memory-retrieval.sh
  • scripts/bench-memory-walk.sh
  • src/openhuman/agent_memory/README.md
  • src/openhuman/agent_memory/mod.rs
  • src/openhuman/agent_memory/ops.rs
  • src/openhuman/agent_memory/tools.rs
  • src/openhuman/agent_memory/types.rs
  • src/openhuman/memory/query/smart_walk.rs
  • src/openhuman/tools/mod.rs
  • tests/agent_retrieval_e2e.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/openhuman/agent_memory/mod.rs
  • src/openhuman/tools/mod.rs
  • src/openhuman/agent_memory/types.rs
  • src/openhuman/agent_memory/ops.rs
  • scripts/bench-memory-walk.sh

Comment thread scripts/bench-memory-retrieval.sh
Comment thread src/openhuman/agent_memory/tools.rs
- Guard CONTENT_ROOT pipeline in bench script so missing users dir
  gets an explicit error instead of silent exit under set -euo pipefail
- Clamp max_turns to [1, 20] to match schema minimum
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 6, 2026
… wiring test

- Add agent_memory entry to RESOURCE_CATALOG so catalog_mirrors_builtins passes
- Update presentation_agent grounding tools assertion: memory_tree/query_memory
  replaced by call_memory_agent
senamakel added a commit to nocstah/openhuman that referenced this pull request Sep 11, 2026
M3gA-Mind added a commit to M3gA-Mind/openhuman that referenced this pull request Sep 18, 2026
Clear every real KNOWN_UNCALLABLE row from the fleet prompt invariant.

- Workspace section names shell/pwd only when shell is callable.
- planner, profile_memory_agent, trigger_reactor: drop stale
  memory_recall/memory_forget mentions (tinyhumansai#3421 replaced recall with
  injected memory).
- code_executor: GitHub state ops go back to the caller via Handoff
  Plan; keep the never-shell-gh rule.
- morning_briefing, skill_executor, context_scout: name the packed
  tools by their use_skill route; record at the workflows pack why
  skill_executor/context_scout are not owners (run_skill closure).
- tools_agent, tool_maker: name shell (and file_write for tool_maker)
  in their own prompt instead of relying on the shared sentence.
- workflow_builder: its shell node kind becomes a collision row in
  place of the removed wildcard shell row.
M3gA-Mind added a commit to M3gA-Mind/openhuman that referenced this pull request Sep 18, 2026
Clear every real KNOWN_UNCALLABLE row from the fleet prompt invariant.

- Workspace section names shell/pwd only when shell is callable.
- planner, profile_memory_agent, trigger_reactor: drop stale
  memory_recall/memory_forget mentions (tinyhumansai#3421 replaced recall with
  injected memory).
- code_executor: GitHub state ops go back to the caller via Handoff
  Plan; keep the never-shell-gh rule.
- morning_briefing, skill_executor, context_scout: name the packed
  tools by their use_skill route; record at the workflows pack why
  skill_executor/context_scout are not owners (run_skill closure).
- tools_agent, tool_maker: name shell (and file_write for tool_maker)
  in their own prompt instead of relying on the shared sentence.
- workflow_builder: its shell node kind becomes a collision row in
  place of the removed wildcard shell row.
M3gA-Mind added a commit to M3gA-Mind/openhuman that referenced this pull request Sep 18, 2026
Clear every real KNOWN_UNCALLABLE row from the fleet prompt invariant.

- Workspace section names shell/pwd only when shell is callable.
- planner, profile_memory_agent, trigger_reactor: drop stale
  memory_recall/memory_forget mentions (tinyhumansai#3421 replaced recall with
  injected memory).
- code_executor: GitHub state ops go back to the caller via Handoff
  Plan; keep the never-shell-gh rule.
- morning_briefing, skill_executor, context_scout: name the packed
  tools by their use_skill route; record at the workflows pack why
  skill_executor/context_scout are not owners (run_skill closure).
- tools_agent, tool_maker: name shell (and file_write for tool_maker)
  in their own prompt instead of relying on the shared sentence.
- workflow_builder: its shell node kind becomes a collision row in
  place of the removed wildcard shell row.
M3gA-Mind added a commit to M3gA-Mind/openhuman that referenced this pull request Sep 18, 2026
Clear every real KNOWN_UNCALLABLE row from the fleet prompt invariant.

- Workspace section names shell/pwd only when shell is callable.
- planner, profile_memory_agent, trigger_reactor: drop stale
  memory_recall/memory_forget mentions (tinyhumansai#3421 replaced recall with
  injected memory).
- code_executor: GitHub state ops go back to the caller via Handoff
  Plan; keep the never-shell-gh rule.
- morning_briefing, skill_executor, context_scout: name the packed
  tools by their use_skill route; record at the workflows pack why
  skill_executor/context_scout are not owners (run_skill closure).
- tools_agent, tool_maker: name shell (and file_write for tool_maker)
  in their own prompt instead of relying on the shared sentence.
- workflow_builder: its shell node kind becomes a collision row in
  place of the removed wildcard shell row.
M3gA-Mind added a commit to M3gA-Mind/openhuman that referenced this pull request Sep 18, 2026
Clear every real KNOWN_UNCALLABLE row from the fleet prompt invariant.

- Workspace section names shell/pwd only when shell is callable.
- planner, profile_memory_agent, trigger_reactor: drop stale
  memory_recall/memory_forget mentions (tinyhumansai#3421 replaced recall with
  injected memory).
- code_executor: GitHub state ops go back to the caller via Handoff
  Plan; keep the never-shell-gh rule.
- morning_briefing, skill_executor, context_scout: name the packed
  tools by their use_skill route; record at the workflows pack why
  skill_executor/context_scout are not owners (run_skill closure).
- tools_agent, tool_maker: name shell (and file_write for tool_maker)
  in their own prompt instead of relying on the shared sentence.
- workflow_builder: its shell node kind becomes a collision row in
  place of the removed wildcard shell row.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. feature Net-new user-facing capability or product behavior. memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant