Skip to content

feat(memory): expose compiled flavour profiles via a read-only memory_flavour tool - #5175

Merged
graycyrus merged 4 commits into
tinyhumansai:mainfrom
graycyrus:feat/memory-flavour-tool
Jul 24, 2026
Merged

feat(memory): expose compiled flavour profiles via a read-only memory_flavour tool#5175
graycyrus merged 4 commits into
tinyhumansai:mainfrom
graycyrus:feat/memory-flavour-tool

Conversation

@graycyrus

@graycyrus graycyrus commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds memory_flavour, a new read-only agent tool that reads the compiled persona flavour profile for one of the seven PersonaFacet lenses (communication, coding_style, stack, workflow, environment, directives, anti_preferences).
  • Wires previously-unread tinycortex flavoured-tree profiles (compiled via compile_flavoured_root) into the agent tool surface for the first time — persona ingestion built these profiles but nothing surfaced them to the agent loop.
  • Genuinely read-only: both permission_level() and permission_level_with_args() are overridden to unconditionally return ReadOnly, avoiding the args-aware permission gap the memory_tree tool previously had.
  • Unbuilt/empty profiles return a clear ToolResult::success("No profile built yet for <facet>. Run persona ingestion first, then try again.") — never an error, never a fabricated profile.
  • Registered in all_tools_with_runtime alongside the other memory_* tools; classified under DomainGroup::Memory automatically via the existing memory_ name-prefix routing (no gating changes needed).

Problem

Solution

  • New MemoryFlavourTool (src/openhuman/memory/tools/flavour.rs), mirroring the existing memory_doctor/memory_recall tool shape (Arc<Config>, mapped via memory_config_from).
  • execute() validates the flavour arg via PersonaFacet::parse_loose (accepts aliases like comms, coding, env, rules, dislikes), then:
    1. Fast path — reads the fixed-path compiled artifact off disk directly if it already exists with a non-empty body.
    2. Slow path — looks up the flavoured tree via get_tree_by_scope(..., TreeKind::Flavoured, ...) and (re)compiles its root via compile_flavoured_root; a missing tree or an empty compiled body both resolve to the same clear "no profile built yet" success message rather than an error.
    3. A compile_flavoured_root/lookup Err is logged (tracing::warn!) and surfaced as a non-error "could not be compiled" message, never a fabricated profile.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy — inline unit tests in flavour.rs (name/schema, both permission overrides, missing/empty/unknown flavour errors, valid-flavour-no-tree-yet success, 5 facet aliases) plus a new tests/json_rpc_e2e.rs::memory_flavour_agent_tool_e2e_5172 covering registration reachability, the no-profile-yet success path, and the unknown-flavour error path.
  • N/A: could not run cargo llvm-cov/pnpm test:rust locally in this environment (no-build constraint on this task) — the new file is fully covered by the added unit + e2e tests; CI's rust-core-coverage lane will validate the ≥80% diff-coverage gate.
  • N/A: no individual agent tool (including the existing memory_doctor/memory_recall) has a row in the coverage matrix; this follows the same convention.
  • N/A: no coverage-matrix rows changed.
  • No new external network dependencies introduced — pure local SQLite/filesystem reads via the existing tinycortex engine, no new crates.
  • N/A: does not touch release-cut/manual-smoke surfaces (backend agent tool only, no UI).
  • Linked issue closed via Closes #5172 below.

Impact

  • Runtime: Rust core only (src/openhuman/memory/tools/flavour.rs, src/openhuman/memory/tools.rs, src/openhuman/tools/ops.rs); no frontend or Tauri shell changes. No new dependencies, no feature-gate changes.

Related

Summary by CodeRabbit

  • New Features
    • Added a new read-only memory_flavour tool to retrieve compiled persona “flavour” profiles (including accepted aliases).
    • Integrated memory_flavour into the default tool registry and enabled it for relevant memory/agent flows via configuration and retrieval prompts.
  • Bug Fixes
    • Added argument validation and safe fallback behavior when profiles aren’t built yet or compilation/storage lookups fail.
  • Tests
    • Added an end-to-end JSON-RPC test covering tool registration, fresh-workspace behavior, and unknown flavour rejection.

…sona profiles

Persona ingestion distills a person's coding-agent history into seven
PersonaFacet flavoured trees (communication, coding_style, stack, workflow,
environment, directives, anti_preferences), each compiled into a small
prompt-ready markdown profile via tinycortex's compile_flavoured_root. Until
now nothing surfaced those compiled profiles to the agent loop — the
ingested data sat unread.

memory_flavour lets an agent pull one facet's profile on demand. It is
genuinely read-only: both permission_level() and permission_level_with_args()
are overridden to unconditionally return ReadOnly (not left to the trait
default), and an unbuilt/empty profile returns a clear "no profile built
yet" ToolResult::success message rather than an error or a fabricated
profile.

Closes tinyhumansai#5172
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0cccd293-eec5-41b0-ba16-c7ae2b15acd1

📥 Commits

Reviewing files that changed from the base of the PR and between 47fb6f5 and 81ab1dc.

📒 Files selected for processing (7)
  • src/openhuman/agent_memory/agent/agent.toml
  • src/openhuman/agent_memory/agent/prompt.md
  • src/openhuman/agent_registry/agents/context_scout/agent.toml
  • src/openhuman/agent_registry/agents/context_scout/prompt.md
  • src/openhuman/agent_registry/agents/profile_memory_agent/agent.toml
  • src/openhuman/agent_registry/agents/profile_memory_agent/prompt.md
  • src/openhuman/memory/tools/flavour.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/openhuman/memory/tools/flavour.rs

📝 Walkthrough

Walkthrough

Adds the read-only memory_flavour tool, exposes compiled persona profiles through the default registry and configured agents, and adds unit and JSON-RPC coverage for validation and empty-profile behavior.

Changes

Memory flavour retrieval

Layer / File(s) Summary
Flavour tool contract and retrieval
src/openhuman/memory/tools.rs, src/openhuman/memory/tools/flavour.rs
Defines MemoryFlavourTool, validates flavour arguments, enforces read-only access, reads compiled profiles, and recompiles missing profiles when possible.
Registry and agent wiring
src/openhuman/tools/ops.rs, src/openhuman/agent_memory/agent/*, src/openhuman/agent_registry/agents/*
Registers memory_flavour and adds guidance for using it to retrieve distilled style and preference profiles.
Tool and JSON-RPC validation
src/openhuman/memory/tools/flavour.rs, tests/json_rpc_e2e.rs
Tests metadata, permissions, aliases, invalid arguments, empty-profile responses, registration, and unknown flavours.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Agent
  participant ToolRegistry
  participant MemoryFlavourTool
  participant TreeStore
  Agent->>ToolRegistry: Request memory_flavour
  ToolRegistry->>MemoryFlavourTool: Execute flavour argument
  MemoryFlavourTool->>MemoryFlavourTool: Read compiled profile
  MemoryFlavourTool->>TreeStore: Lookup and compile when needed
  TreeStore-->>MemoryFlavourTool: Return tree or no tree
  MemoryFlavourTool-->>Agent: Return profile or no-profile response
Loading

Suggested labels: feature, memory, agent, rust-core

Suggested reviewers: senamakel

Poem

A rabbit found a profile’s trail,
Through flavoured paths and markdown mail.
“Read-only,” said Bun, “no edits today—”
The empty tree answered, “Not built yet, okay!”
New style clues now join the play.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 70.59% 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 accurately states the main change: adding a read-only memory_flavour tool for compiled flavour profiles.
Linked Issues check ✅ Passed The tool, permissions, registry wiring, and tests align with #5172's requirements for exposed profiles, empty responses, and ReadOnly access.
Out of Scope Changes check ✅ Passed The registry and prompt updates stay focused on wiring memory_flavour into agents and tests; no unrelated changes stand out.

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

Collapse the multi-line anyhow!() in parse_loose error handling onto one line per rustfmt. The other Rust Quality diffs on this branch (caps.rs, provider.rs) are pre-existing on upstream/main (introduced by tinyhumansai#5151 et al.) — main head e780277 already fails Rust Quality — and are not touched by this PR.
@graycyrus
graycyrus marked this pull request as ready for review July 24, 2026 10:36
@graycyrus
graycyrus requested a review from a team July 24, 2026 10:36
@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. working A PR that is being worked on by the team. labels Jul 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47fb6f5017

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

// (communication/coding_style/stack/workflow/environment/directives/
// anti_preferences) that persona ingestion builds but nothing
// previously surfaced to the agent loop.
Box::new(MemoryFlavourTool::new(config.clone())),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Add memory_flavour to the named agent allowlists

Registering the tool here makes it part of the global registry, but normal chat sessions are built against the orchestrator definition and memory work is delegated to agent_memory/profile_memory_agent, all of which use ToolScope::Named allowlists. I checked those TOML allowlists and none include memory_flavour, so in the actual CLI/Tauri chat paths the harness filters this tool out and the model never sees or calls it; only wildcard/custom sessions would. Please add the tool to the appropriate named allowlist(s) and prompt guidance, or this feature remains unreachable for the intended agent loop.

Useful? React with 👍 / 👎.

Comment thread src/openhuman/memory/tools/flavour.rs Outdated
Comment on lines +152 to +154
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return tool errors on profile lookup failures

When a flavoured tree exists but compilation fails, for example because the tree state is corrupt or the compiled artifact path cannot be written, this branch returns ToolResult::success(...), so is_error stays false and the harness/telemetry records a failed profile read as a successful tool call; the lookup-error branch below does the same. Return ToolResult::error or propagate for real store/compile failures, reserving success for the expected “no profile built yet” case.

Useful? React with 👍 / 👎.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026

Copy link
Copy Markdown

Greptile Summary

This PR closes #5172 by surfacing the compiled persona flavour profiles that tinycortex's persona ingestion already builds (one per PersonaFacet lens) to the agent loop via a new read-only memory_flavour tool. All three issues flagged in the previous review cycle — YAML front-matter leakage on both paths, the malformed-front-matter fallback returning the wrong slice, and missing debug tracing on happy paths — are correctly resolved in this revision.

  • MemoryFlavourTool (flavour.rs): fast path reads the compiled artifact off disk and correctly strips front matter via body_after_front_matter before returning; slow path queries the tree store and re-compiles, also stripping front matter; debug! instrumentation present on every branch; both permission_level() and permission_level_with_args() unconditionally return ReadOnly.
  • Registration: tool added to all_tools_with_runtime in ops.rs and gated into the named allowlists of three agents (agent_memory, context_scout, profile_memory_agent) with updated prompt guidance.
  • Tests: inline unit tests cover name/schema, both permission overrides, missing/empty/unknown-flavour validation, aliases, and the no-tree-yet success path; memory_flavour_agent_tool_e2e_5172 verifies registration reachability and the fresh-workspace contract end-to-end.

Confidence Score: 5/5

Safe to merge — the change is purely additive, read-only, and well-tested; no existing tool behaviour is modified.

All three issues from the previous review cycle are addressed. The front-matter stripping is applied correctly on both the fast and slow paths, the malformed-front-matter fallback returns the right slice, and debug tracing covers every execution branch. The tool is unconditionally read-only, introduces no new dependencies, and is covered by both unit and e2e tests.

No files require special attention.

Important Files Changed

Filename Overview
src/openhuman/memory/tools/flavour.rs New MemoryFlavourTool: fast-path disk read + slow-path tree-store lookup; both paths correctly strip YAML front matter via body_after_front_matter before returning; debug tracing on every branch; comprehensive unit tests. All three issues from the prior review cycle are resolved.
src/openhuman/memory/tools.rs Adds mod flavour and re-exports MemoryFlavourTool alongside the existing memory tools; no functional changes to other tools.
src/openhuman/tools/ops.rs Registers MemoryFlavourTool in all_tools_with_runtime between MemoryDoctorTool and MemoryQueryTool; comment ties registration back to issue #5172.
tests/json_rpc_e2e.rs Adds memory_flavour_agent_tool_e2e_5172: verifies tool name, no-profile-yet success path, and unknown-slug rejection — covers registration reachability end-to-end.
src/openhuman/agent_memory/agent/agent.toml Adds memory_flavour to the agent_memory agent's named tool allowlist with an explanatory comment.
src/openhuman/agent_registry/agents/context_scout/agent.toml Adds memory_flavour to the context_scout agent's named tool allowlist; read-only and safe for the scout's usage pattern.
src/openhuman/agent_registry/agents/profile_memory_agent/agent.toml Adds memory_flavour to the profile_memory_agent's named tool allowlist alongside other read tools.

Sequence Diagram

sequenceDiagram
    participant Agent
    participant MemoryFlavourTool
    participant FS as Filesystem
    participant TreeStore as TreeStore (SQLite)

    Agent->>MemoryFlavourTool: "execute({flavour: "coding_style"})"
    MemoryFlavourTool->>MemoryFlavourTool: PersonaFacet::parse_loose()
    alt Invalid / empty slug
        MemoryFlavourTool-->>Agent: Err(anyhow)
    end

    MemoryFlavourTool->>FS: is_file(flavoured_root_abs_path)
    alt Fast path - artifact exists on disk
        FS-->>MemoryFlavourTool: read_to_string Ok(content)
        MemoryFlavourTool->>MemoryFlavourTool: body_after_front_matter(content)
        alt body non-empty
            MemoryFlavourTool-->>Agent: ToolResult::success(body)
        end
    end

    MemoryFlavourTool->>TreeStore: get_tree_by_scope(Flavoured, scope)
    alt No tree found
        TreeStore-->>MemoryFlavourTool: Ok(None)
        MemoryFlavourTool-->>Agent: ToolResult::success(No profile built yet)
    else Lookup error
        TreeStore-->>MemoryFlavourTool: Err(e)
        MemoryFlavourTool-->>Agent: ToolResult::error(Failed to look up)
    else Tree found
        TreeStore-->>MemoryFlavourTool: Ok(Some(tree))
        MemoryFlavourTool->>FS: compile_flavoured_root(mc, tree.id)
        alt Compile succeeds, body non-empty
            FS-->>MemoryFlavourTool: Ok(markdown)
            MemoryFlavourTool->>MemoryFlavourTool: body_after_front_matter(markdown)
            MemoryFlavourTool-->>Agent: ToolResult::success(body)
        else Compile succeeds, body empty
            FS-->>MemoryFlavourTool: Ok(markdown)
            MemoryFlavourTool-->>Agent: ToolResult::success(No profile built yet)
        else Compile error
            FS-->>MemoryFlavourTool: Err(e)
            MemoryFlavourTool-->>Agent: ToolResult::error(Failed to compile)
        end
    end
Loading

Reviews (2): Last reviewed commit: "fix(memory): address review — strip fron..." | Re-trigger Greptile

Comment thread src/openhuman/memory/tools/flavour.rs
Comment thread src/openhuman/memory/tools/flavour.rs Outdated
Comment thread src/openhuman/memory/tools/flavour.rs
Comment thread src/openhuman/memory/tools/flavour.rs

@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: 1

🧹 Nitpick comments (2)
src/openhuman/memory/tools/flavour.rs (1)

171-262: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No test exercises the actual successful-profile path.

Every test here covers validation, permissions, or the "no profile built yet" fallback. None verifies the primary feature: reading a profile that actually has content (either via the fast-path file read at flavoured_root_abs_path, or via compile_flavoured_root returning a non-empty body). Given the PR's stated goal — "Return profiles for facets such as communication and coding_style" — this success path is untested.

A test could write a fake compiled artifact (front matter + body) directly to the path returned by flavoured_root_abs_path(&mc, &scope) and assert execute returns that body via the fast path, exercising body_after_front_matter end-to-end too.

🤖 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/memory/tools/flavour.rs` around lines 171 - 262, Add a
success-path test alongside the existing MemoryFlavourTool tests that creates a
compiled profile artifact at the path produced by flavoured_root_abs_path for a
valid flavour and scope, including front matter and a non-empty body. Execute
the tool and assert it succeeds, is not an error, and returns the profile body,
thereby exercising the fast-path file read and body_after_front_matter behavior.
tests/json_rpc_e2e.rs (1)

14841-14887: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test bypasses JSON-RPC dispatch despite living in the JSON-RPC E2E suite.

memory_flavour_agent_tool_e2e_5172 constructs MemoryFlavourTool directly and calls execute(), which is unit-level coverage, not an actual JSON-RPC round trip. It doesn't confirm the tool is reachable/permission-enforced through the real tool_call JSON-RPC dispatch path referenced in the PR objectives.

Consider routing this test through the same JSON-RPC dispatch helper other tests in this file use for tool-call verification, or moving it to a plain unit test file if a dispatch-level test already exists elsewhere for memory_flavour.
As per coding guidelines, "Follow the workflow: specify, prove in Rust, prove over JSON-RPC, surface in the UI, and test at unit and E2E levels."

🤖 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 `@tests/json_rpc_e2e.rs` around lines 14841 - 14887, Update
memory_flavour_agent_tool_e2e_5172 to invoke memory_flavour through the existing
JSON-RPC tool_call dispatch helper used by nearby tests instead of constructing
MemoryFlavourTool and calling execute() directly. Preserve assertions for
successful no-profile behavior and unknown-flavour rejection, while ensuring the
round trip exercises registration and permission enforcement; if equivalent
dispatch coverage already exists, move these direct-execution assertions to an
appropriate unit test instead.

Source: Coding guidelines

🤖 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/openhuman/memory/tools/flavour.rs`:
- Around line 130-167: Update the outer Err(err) arm handling get_tree_by_scope
in the flavoured-profile lookup flow to report a tree lookup failure rather than
reusing the compile-failure message. Keep the existing compile-specific message
in the compile_flavoured_root error arm unchanged, and preserve the current
error details and successful result behavior.

---

Nitpick comments:
In `@src/openhuman/memory/tools/flavour.rs`:
- Around line 171-262: Add a success-path test alongside the existing
MemoryFlavourTool tests that creates a compiled profile artifact at the path
produced by flavoured_root_abs_path for a valid flavour and scope, including
front matter and a non-empty body. Execute the tool and assert it succeeds, is
not an error, and returns the profile body, thereby exercising the fast-path
file read and body_after_front_matter behavior.

In `@tests/json_rpc_e2e.rs`:
- Around line 14841-14887: Update memory_flavour_agent_tool_e2e_5172 to invoke
memory_flavour through the existing JSON-RPC tool_call dispatch helper used by
nearby tests instead of constructing MemoryFlavourTool and calling execute()
directly. Preserve assertions for successful no-profile behavior and
unknown-flavour rejection, while ensuring the round trip exercises registration
and permission enforcement; if equivalent dispatch coverage already exists, move
these direct-execution assertions to an appropriate unit test instead.
🪄 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: 0f26aeee-4cde-43d8-a7b4-16da7e515a51

📥 Commits

Reviewing files that changed from the base of the PR and between 7db104b and 47fb6f5.

📒 Files selected for processing (4)
  • src/openhuman/memory/tools.rs
  • src/openhuman/memory/tools/flavour.rs
  • src/openhuman/tools/ops.rs
  • tests/json_rpc_e2e.rs

Comment on lines +130 to +167
match get_tree_by_scope(&mc, TreeKind::Flavoured, &scope) {
Ok(None) => Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, then try \
again."
))),
Ok(Some(tree)) => match compile_flavoured_root(&mc, &tree.id) {
Ok(markdown) => {
if body_after_front_matter(&markdown).trim().is_empty() {
Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, \
then try again."
)))
} else {
Ok(ToolResult::success(markdown))
}
}
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to compile flavoured profile"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))
}
},
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to look up flavoured tree"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))
}
}

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Lookup failure is mislabeled as a compile failure.

The Err(err) arm at Line 157 (from get_tree_by_scope, a tree-lookup failure) reuses the same "Profile for {heading} could not be compiled: {err}" message as the genuine compile failure at Line 146. An agent/user reading this will think compilation broke when the tree lookup itself failed, which muddies troubleshooting.

🐛 Proposed fix to distinguish lookup vs compile failures
             Err(err) => {
                 tracing::warn!(
                     %err,
                     flavour = flavour_raw,
                     "[memory_flavour] failed to look up flavoured tree"
                 );
                 Ok(ToolResult::success(format!(
-                    "Profile for {heading} could not be compiled: {err}"
+                    "Profile for {heading} could not be looked up: {err}"
                 )))
             }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
match get_tree_by_scope(&mc, TreeKind::Flavoured, &scope) {
Ok(None) => Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, then try \
again."
))),
Ok(Some(tree)) => match compile_flavoured_root(&mc, &tree.id) {
Ok(markdown) => {
if body_after_front_matter(&markdown).trim().is_empty() {
Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, \
then try again."
)))
} else {
Ok(ToolResult::success(markdown))
}
}
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to compile flavoured profile"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))
}
},
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to look up flavoured tree"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))
}
}
match get_tree_by_scope(&mc, TreeKind::Flavoured, &scope) {
Ok(None) => Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, then try \
again."
))),
Ok(Some(tree)) => match compile_flavoured_root(&mc, &tree.id) {
Ok(markdown) => {
if body_after_front_matter(&markdown).trim().is_empty() {
Ok(ToolResult::success(format!(
"No profile built yet for {heading}. Run persona ingestion first, \
then try again."
)))
} else {
Ok(ToolResult::success(markdown))
}
}
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to compile flavoured profile"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be compiled: {err}"
)))
}
},
Err(err) => {
tracing::warn!(
%err,
flavour = flavour_raw,
"[memory_flavour] failed to look up flavoured tree"
);
Ok(ToolResult::success(format!(
"Profile for {heading} could not be looked up: {err}"
)))
}
}
🤖 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/memory/tools/flavour.rs` around lines 130 - 167, Update the
outer Err(err) arm handling get_tree_by_scope in the flavoured-profile lookup
flow to report a tree lookup failure rather than reusing the compile-failure
message. Keep the existing compile-specific message in the
compile_flavoured_root error arm unchanged, and preserve the current error
details and successful result behavior.

…res, reachability, tracing

Three bots flagged real issues on the memory_flavour tool (PR tinyhumansai#5175):

- Greptile P1: both read paths (fast disk-cache hit and the slow
  compile-then-read path) returned the raw compiled artifact, including its
  `---\n...\n---\n` YAML front matter, despite the tool description promising
  markdown prose. Both paths now strip to the body via
  body_after_front_matter() before returning.
- Greptile P2: body_after_front_matter's malformed-front-matter fallback
  (opener present, no closer) returned the full original content, leaking the
  `---` opener. Now falls back to `rest` (everything after the opener).
- Codex P2 / CodeRabbit: genuine failures (tree lookup error, compile error)
  were wrapped in ToolResult::success(...), so is_error stayed false and
  telemetry recorded failed reads as successes. Now returns
  ToolResult::error(...) with distinct "look up" vs "compile" wording; the
  expected "no profile built yet" case is unchanged (still success).
- Greptile P2: added tracing::debug! at entry, fast-path hit, fast->slow
  fallthrough, tree-lookup outcome (none vs found+compiling), and compiled
  body return, per CLAUDE.md's verbose-diagnostics rule. Logs slugs/lengths
  only, never profile content.
- Codex P2 (reachability): the tool was registered globally but excluded from
  every agent's `[tools] named` allowlist, so ToolScope::Named filtering hid
  it from the harness entirely. Added "memory_flavour" (with a prompt note)
  to agent_memory, profile_memory_agent, and context_scout — the three
  read-oriented memory/profile agents where it belongs.
@coderabbitai coderabbitai Bot added 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/. and removed working A PR that is being worked on by the team. labels Jul 24, 2026
@graycyrus
graycyrus merged commit 2d6064c into tinyhumansai:main Jul 24, 2026
25 of 29 checks passed
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.

feat(memory): expose compiled flavour profiles via a read-only memory_flavour tool

1 participant