Skip to content

feat(prompt): per-agent PROFILE.md + MEMORY.md injection, 2K-char cap#550

Merged
senamakel merged 9 commits intotinyhumansai:mainfrom
senamakel:fix/prompts-v4
Apr 14, 2026
Merged

feat(prompt): per-agent PROFILE.md + MEMORY.md injection, 2K-char cap#550
senamakel merged 9 commits intotinyhumansai:mainfrom
senamakel:fix/prompts-v4

Conversation

@senamakel
Copy link
Copy Markdown
Member

@senamakel senamakel commented Apr 14, 2026

Summary

  • Fix welcome agent losing PROFILE.md context: onboarding enrichment writes the file but the welcome sub-agent never saw it because the renderer bundled PROFILE.md inside the identity block that omit_identity = true stripped.
  • Turn PROFILE.md and MEMORY.md inclusion into explicit, per-agent config (omit_profile / omit_memory_md in agent.toml), opt-in on user-facing agents only.
  • Cap both files at USER_FILE_MAX_CHARS = 2_000 (~1000 tokens) so growing on-disk files can't balloon the system prompt.
  • Harden scripts/debug-agent-prompts.sh so prompt dumps reflect what the LLM actually sees.

Problem

The welcome agent's prompt was missing PROFILE.md even though the onboarding pipeline had written it to the workspace. Root cause was in src/openhuman/context/prompt.rs: the subagent renderer's identity block (SOUL.md / IDENTITY.md / PROFILE.md) was gated as one unit on include_identity, and the welcome agent sets omit_identity = true (it has its own voice), which silently dropped PROFILE.md along with the SOUL/IDENTITY preamble. Once that was untangled, the broader question surfaced: which agents should see PROFILE.md (and MEMORY.md) at all, and what budget should these user-specific files occupy?

Solution

Per-file agent config flagsAgentDefinition::omit_profile and AgentDefinition::omit_memory_md (both #[serde(default = true)]), threaded via SubagentRenderOptions::include_profile / include_memory_md into render_subagent_system_prompt, and via a new AgentBuilder::omit_memory_md() / omit_profile() pair + PromptContext fields into IdentitySection::build for the main-agent path. Opt-in on four agents only: welcome, orchestrator, trigger_triage, trigger_reactor.

2000-char budget — new inject_workspace_file_capped(prompt, dir, filename, max_chars) helper; PROFILE.md and MEMORY.md use USER_FILE_MAX_CHARS = 2_000, bootstrap files (SOUL / IDENTITY / HEARTBEAT) keep the existing 20K budget via a thin wrapper.

KV-cache contract documented in code — rustdoc on omit_memory_md, the injection sites, and the capped helper spells out that rendered bytes are frozen per session. Mid-session writes to either file do NOT update the in-flight system prompt; they land on the next session. Backed by a new rendered_subagent_system_prompt_is_byte_stable_across_repeat_calls test.

Debug dumper fixesscripts/debug-agent-prompts.sh:

  • Always rebuild openhuman-core (the -x existence-only guard let a stale binary survive across agent-registry changes, silently skipping newly added agents like welcome).
  • Wipe-and-recreate prompt-dumps/ with no timestamp subfolder for cleaner diffs; safety-guarded against wiping $HOME///repo root.
  • Run against the currently-logged-in user's workspace (resolved via ~/.openhuman/active_user.toml) so dumps reflect what the LLM actually sees, not an empty mktemp -d.

Submission Checklist

  • Unit tests — 7 new tests in src/openhuman/context/prompt.rs (25 total, all green): PROFILE.md / MEMORY.md inject-when-enabled, skip-when-disabled, welcome-flags-load-PROFILE, narrow-flags-skip-PROFILE, 2000-char cap on both files, and byte-stability across repeat spawns (the KV-cache pin).
  • E2E / integration — Verified end-to-end via scripts/debug-agent-prompts.sh against a real user workspace: PROFILE.md and MEMORY.md appear only in the 4 opt-in dumps (welcome, orchestrator, trigger_triage, trigger_reactor) + main (= orchestrator), and the truncation marker fires at exactly 2000 chars on a seeded oversize file.
  • Doc comments — Rustdoc on both flags, USER_FILE_MAX_CHARS, inject_workspace_file_capped, and the renderer comment blocks explaining the session-freeze / KV-cache contract.
  • Inline comments — Non-obvious bits (why fork_definition keeps both flags at false, why the narrow renderer path has a separate gate, why the dumper no longer uses a mktemp workspace) annotated inline.

Impact

  • Runtime: only user-facing agents (welcome, orchestrator, trigger_triage, trigger_reactor) now see PROFILE.md + MEMORY.md. Narrow specialists (planner, code_executor, skills_agent, tool_maker, researcher, critic, archivist, morning_briefing) default to omit_profile = true / omit_memory_md = true and stay lean.
  • Prompt footprint: each user-specific file contributes at most ~1000 tokens regardless of on-disk size; far below the 20K-char budget SOUL/IDENTITY already use.
  • Cache behavior: rendered subagent prompts are a pure function of (archetype body, tool set, workspace files at load time, model name, options) — pinned by an explicit byte-stability test. Re-entry of the same definition inside one session reuses the backend's prefix cache.
  • Compatibility: new flags have #[serde(default = true)], so existing custom agents/*.toml overrides in a user workspace keep working without edits (and stay lean — they won't suddenly start loading PROFILE/MEMORY).

Related

  • Issue(s): n/a (discovered while diagnosing why the welcome agent wasn't personalising replies after onboarding).
  • Follow-up PR(s)/TODOs: a future pass could extract the omit_* + USER_FILE_MAX_CHARS logic into a dedicated prompt::workspace_injection module if we add a third user-file (e.g. GOALS.md), but two files doesn't warrant it yet.

Summary by CodeRabbit

  • New Features

    • Several agents now include user profile and long-term memory content in their prompts for richer, more personalized and context-aware responses.
  • Chores

    • Improved debug tooling: more reliable workspace resolution, consistent output location, and safer run-time output handling.
    • Test suites and helpers updated to exercise and validate the new agent context settings.

- Updated the `debug-agent-prompts.sh` script to always run `cargo build`, ensuring the latest binary is used and preventing stale binaries from affecting agent behavior.
- Modified the output directory handling to wipe and recreate it at the start of each run, ensuring a clean snapshot of the current agent set.
- Enhanced the `render_subagent_system_prompt` function to unconditionally inject `PROFILE.md`, ensuring it is included even when identity information is omitted, thus improving personalization for agents like `welcome`.
- Added tests to verify the correct injection of `PROFILE.md` under various conditions, ensuring robust functionality and preventing regressions in prompt rendering.
… user's workspace

- Updated the `debug-agent-prompts.sh` script to point to the real user's workspace, ensuring onboarding-generated files like `PROFILE.md` are included in the dump.
- Improved workspace resolution logic to prioritize the active user's workspace, falling back to default paths as necessary.
- Added error handling for cases where the workspace is not found, providing clear guidance for users to complete onboarding or specify a different workspace.
- Enhanced output to include the presence state of `PROFILE.md`, improving visibility into the onboarding process.
- Updated agent TOML configurations for orchestrator, trigger reactor, trigger triage, and welcome agents to include user profile data by setting `omit_profile = false`. This allows agents to personalize interactions based on user context derived from `PROFILE.md`.
- Refactored the `AgentDefinition` struct to include a new `omit_profile` field, ensuring that agents can opt-in to utilize user profile information.
- Enhanced prompt rendering logic to conditionally inject `PROFILE.md` based on the `omit_profile` flag, improving the relevance and personalization of agent responses.
- Updated tests to verify the correct behavior of profile inclusion across various agents, ensuring robust functionality and preventing regressions.
…le management

- Added a new `omit_profile` field to the `AgentBuilder` struct, allowing agents to specify whether to include user profile data in their responses.
- Updated the `Agent` struct to mirror the `omit_profile` flag, ensuring that the profile inclusion logic is consistent across agent instances.
- Enhanced the `omit_profile` method in `AgentBuilder` to facilitate the configuration of this flag during agent construction.
- Adjusted the default behavior to omit profiles for legacy agents while allowing opt-in for specific agents that require user context.
- Updated documentation to clarify the purpose and usage of the `omit_profile` flag in agent definitions.
- Introduced an `omit_profile` flag in the `AgentBuilder` and `Agent` to control the inclusion of user profile data in responses, defaulting to true for legacy paths.
- Updated the `Agent` struct to utilize the `omit_profile` flag, ensuring consistent profile inclusion logic across agent instances.
- Enhanced prompt rendering logic to conditionally include or exclude `PROFILE.md` based on the `omit_profile` setting, improving personalization for user-facing agents.
- Added tests to verify the correct behavior of profile inclusion and omission across various scenarios, ensuring robust functionality and preventing regressions.
Add `omit_memory_md` to `AgentDefinition` (mirror of `omit_profile`)
and inject `MEMORY.md` alongside `PROFILE.md` in both the main and
sub-agent render paths. Both user-specific files are capped at
`USER_FILE_MAX_CHARS = 2_000` (~1000 tokens each) via a new
`inject_workspace_file_capped` helper so growing on-disk files can't
balloon the system prompt.

Opt-in on the same four user-facing agents (welcome, orchestrator,
trigger_triage, trigger_reactor). Narrow specialists leave it at the
`true` default.

KV-cache contract is documented on the flag, the injection sites, and
the capped helper: rendered bytes are frozen per session, and
mid-session writes only surface on the next session. Pinned with a new
`rendered_subagent_system_prompt_is_byte_stable_across_repeat_calls`
test plus coverage for injection / opt-out / 2000-char cap.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@senamakel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 2 minutes and 57 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 2 minutes and 57 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d06d4c4d-00b5-40d9-bca2-14889dcec4b2

📥 Commits

Reviewing files that changed from the base of the PR and between 0a14ed0 and 3acf8e6.

📒 Files selected for processing (4)
  • scripts/debug-agent-prompts.sh
  • src/openhuman/agent/harness/session/builder.rs
  • src/openhuman/agent/harness/session/turn.rs
  • src/openhuman/context/prompt.rs
📝 Walkthrough

Walkthrough

Threaded two new per-agent flags—omit_profile and omit_memory_md—from TOML into runtime: added fields to AgentDefinition, builder, and Agent; wired them into PromptContext/rendering to conditionally inject PROFILE.md and MEMORY.md (with truncation) and updated the debug script workspace/output behavior.

Changes

Cohort / File(s) Summary
Debug Script Workspace Resolution
scripts/debug-agent-prompts.sh
Now targets real user workspace ($OPENHUMAN_WORKSPACE or ~/.openhuman/active_user.toml / ~/.openhuman/workspace), errors if workspace missing, logs PROFILE.md presence, defaults --out to ./prompt-dumps (no UTC timestamp), wipes/recreates OUT_DIR safely, and always runs cargo build.
Agent Configurations
src/openhuman/agent/agents/orchestrator/agent.toml, src/openhuman/agent/agents/trigger_reactor/agent.toml, src/openhuman/agent/agents/trigger_triage/agent.toml, src/openhuman/agent/agents/welcome/agent.toml
Explicitly set omit_profile = false and omit_memory_md = false to enable inclusion of PROFILE.md and MEMORY.md in these agent prompts.
Agent Definition & Builder Infrastructure
src/openhuman/agent/harness/definition.rs, src/openhuman/agent/harness/session/types.rs, src/openhuman/agent/harness/session/builder.rs
Added omit_profile and omit_memory_md to AgentDefinition (serde default true), extended Agent and AgentBuilder with corresponding fields, and added fluent setters omit_profile(bool) and omit_memory_md(bool) with fallback logic.
Agent Instance & Rendering Integration
src/openhuman/agent/harness/session/turn.rs, src/openhuman/agent/harness/subagent_runner.rs, src/openhuman/agent/harness/builtin_definitions.rs
Passed inverted omit flags into PromptContext (include_profile/include_memory_md), extended SubagentRenderOptions::from_definition_flags to accept new flags, and updated built-in/test definitions to set the new fields.
Prompt Context & Rendering Logic
src/openhuman/context/prompt.rs
Added include_profile/include_memory_md to PromptContext and SubagentRenderOptions; conditional injection of PROFILE.md and MEMORY.md with new inject_workspace_file_capped() and USER_FILE_MAX_CHARS truncation; updated rendering paths and tests to honor flags.
Debug Dump & Tests
src/openhuman/context/debug_dump.rs, src/openhuman/channels/runtime/dispatch.rs, src/openhuman/learning/prompt_sections.rs, src/openhuman/tools/orchestrator_tools.rs
Threaded new omit/include flags into debug dump rendering and updated many test helpers/constructed AgentDefinitions to initialize omit_profile/omit_memory_md consistently.

Sequence Diagram(s)

sequenceDiagram
    participant TOML as Agent TOML Config
    participant Def as AgentDefinition
    participant Builder as AgentBuilder
    participant Agent as Agent Instance
    participant Prompt as PromptContext
    participant Renderer as Prompt Renderer

    TOML->>Def: load omit_profile / omit_memory_md (defaults true)
    Def->>Builder: Agent::from_config_for_agent() passes flags
    Builder->>Agent: set omit_profile / omit_memory_md via builder
    Agent->>Prompt: build_system_prompt (invert to include_*)
    Prompt->>Renderer: provide include_profile & include_memory_md
    Renderer->>Renderer: conditionally inject PROFILE.md (capped)
    Renderer->>Renderer: conditionally inject MEMORY.md (capped)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰
I nibble at prompts with keen delight,
Profile and memory can now take flight,
Builders, defs, and renders line the way,
Workspace files enter only when we say—
Hooray for choices, soft and bright! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding per-agent control over PROFILE.md and MEMORY.md injection with a 2K-character cap, which is the core feature of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

- Removed unnecessary line breaks and adjusted indentation in test files for better consistency and clarity.
- Reformatted the `RewardsCouponSection` test to enhance readability and maintain a uniform style across test cases.
- Ensured that all test cases align with the updated formatting standards, improving overall maintainability.
Copy link
Copy Markdown
Contributor

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

🧹 Nitpick comments (1)
src/openhuman/agent/harness/session/builder.rs (1)

782-818: Log the resolved profile/memory omission flags.

This branch now decides whether PROFILE.md and MEMORY.md reach the session prompt, but the surrounding diagnostics still hide both values. A debug log here would make prompt-shaping regressions much easier to trace.

Possible addition
         let effective_omit_profile = target_def.map(|def| def.omit_profile).unwrap_or(true);
         let effective_omit_memory_md = target_def.map(|def| def.omit_memory_md).unwrap_or(true);
+
+        log::debug!(
+            "[agent::builder] prompt file flags: agent_id={} omit_profile={} omit_memory_md={}",
+            agent_id,
+            effective_omit_profile,
+            effective_omit_memory_md
+        );

As per coding guidelines "Add substantial, development-oriented logs on new/changed flows; include logs at entry/exit points, branch decisions, external calls, retries/timeouts, state transitions, and error handling paths".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/agent/harness/session/builder.rs` around lines 782 - 818, The
code computes effective_omit_profile and effective_omit_memory_md but does not
log their values, making prompt-shaping regressions hard to trace; add a
debug/info log just before constructing the Agent with Agent::builder() that
emits both effective_omit_profile and effective_omit_memory_md (and optionally
agent_id and model_name for context) so callers can see which branch was chosen;
place the log immediately above the Agent::builder() call, using the existing
tracing/logger facility in this module to record the two booleans and minimal
context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/debug-agent-prompts.sh`:
- Around line 104-110: Resolve and validate OUT_DIR before deletion: disallow
relative or symlinked paths by requiring OUT_DIR be absolute (starts with "/")
and canonicalize it (using readlink -f or realpath) into a resolved_out
variable, then compare resolved_out against disallowed targets ("" "/" "${HOME}"
and the canonicalized REPO_ROOT) and reject if it equals any of them or if the
original OUT_DIR is "." or ".."; only call rm -rf on the canonicalized,
validated resolved_out. Ensure checks reference OUT_DIR and REPO_ROOT and
perform symlink resolution so symlinked paths cannot bypass the guard.

In `@src/openhuman/agent/harness/session/turn.rs`:
- Around line 923-924: The debug log currently printing the full system prompt
body (rendered_prompt.text) can leak PROFILE/MEMORY contents when
include_profile or include_memory_md are enabled; change the logging around
where rendered_prompt.text is emitted to omit or redact sensitive content
whenever include_profile == true or include_memory_md == true (or
omit_profile/omit_memory_md are false), e.g., replace the full-body log with
either a short summary, length-limited snippet, or a fixed redaction message
indicating PROFILE/MEMORY were omitted; update the log call(s) that reference
rendered_prompt.text to check include_profile/include_memory_md and avoid
printing full prompt when those flags allow injected sensitive data.

In `@src/openhuman/context/prompt.rs`:
- Around line 1490-1495: Run rustfmt on the changed Rust test hunks and ensure
the file compiles: format the test function
subagent_render_options_invert_definition_flags and the other affected test
blocks (around the ranges near lines 1577-1585 and 1808-1811) so their spacing
and indentation conform to cargo fmt; then run cargo check to ensure no
formatting-induced warnings/errors. Specifically, open
src/openhuman/context/prompt.rs, reformat the test that calls
SubagentRenderOptions::from_definition_flags(true, false, true, false, false)
and the assertions (e.g., assert!(!options.include_identity)), fix any stray
spacing/line breaks per rustfmt, and re-run cargo fmt/cargo check across the
workspace (including root Cargo.toml and app/src-tauri/Cargo.toml) before
committing.
- Around line 392-419: The PROFILE.md and MEMORY.md injections are only inside
IdentitySection so when SystemPromptBuilder::for_subagent() skips
IdentitySection due to omit_identity=true the files never get injected; update
the prompt-building logic so inject_workspace_file_capped is called for
ctx.include_profile and ctx.include_memory_md in the shared subagent rendering
path (e.g., inside render_subagent_system_prompt or
SystemPromptBuilder::for_subagent()) regardless of omit_identity, or move the
injection out of IdentitySection into the common prompt assembly code; reference
inject_workspace_file_capped, ctx.include_profile, ctx.include_memory_md,
SystemPromptBuilder::for_subagent, render_subagent_system_prompt,
IdentitySection, and AgentDefinition::omit_memory_md/omit_profile when making
the change.

---

Nitpick comments:
In `@src/openhuman/agent/harness/session/builder.rs`:
- Around line 782-818: The code computes effective_omit_profile and
effective_omit_memory_md but does not log their values, making prompt-shaping
regressions hard to trace; add a debug/info log just before constructing the
Agent with Agent::builder() that emits both effective_omit_profile and
effective_omit_memory_md (and optionally agent_id and model_name for context) so
callers can see which branch was chosen; place the log immediately above the
Agent::builder() call, using the existing tracing/logger facility in this module
to record the two booleans and minimal context.
🪄 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

Run ID: d6c4772b-4a1c-40aa-ac1d-632436e52b15

📥 Commits

Reviewing files that changed from the base of the PR and between 5a8a7ed and ce60d27.

📒 Files selected for processing (16)
  • scripts/debug-agent-prompts.sh
  • src/openhuman/agent/agents/orchestrator/agent.toml
  • src/openhuman/agent/agents/trigger_reactor/agent.toml
  • src/openhuman/agent/agents/trigger_triage/agent.toml
  • src/openhuman/agent/agents/welcome/agent.toml
  • src/openhuman/agent/harness/builtin_definitions.rs
  • src/openhuman/agent/harness/definition.rs
  • src/openhuman/agent/harness/session/builder.rs
  • src/openhuman/agent/harness/session/turn.rs
  • src/openhuman/agent/harness/session/types.rs
  • src/openhuman/agent/harness/subagent_runner.rs
  • src/openhuman/channels/runtime/dispatch.rs
  • src/openhuman/context/debug_dump.rs
  • src/openhuman/context/prompt.rs
  • src/openhuman/learning/prompt_sections.rs
  • src/openhuman/tools/orchestrator_tools.rs

Comment thread scripts/debug-agent-prompts.sh
Comment on lines +923 to +924
include_profile: !self.omit_profile,
include_memory_md: !self.omit_memory_md,
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.

⚠️ Potential issue | 🟠 Major

Prevent full prompt-body logging now that PROFILE/MEMORY can be injected.

With these flags enabled, rendered_prompt.text can carry user-sensitive PROFILE.md/MEMORY.md data. The existing debug log at Line 93 prints the full system prompt body, which can leak PII/secrets into logs.

🔒 Proposed fix
-            log::debug!("[agent_loop] system prompt body:\n{}", rendered_prompt.text);
+            log::debug!(
+                "[agent_loop] system prompt summary chars={} include_profile={} include_memory_md={}",
+                rendered_prompt.text.chars().count(),
+                !self.omit_profile,
+                !self.omit_memory_md
+            );

As per coding guidelines Never log secrets, API keys, JWTs, credentials, or full PII in Rust logs; redact or omit sensitive fields.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/agent/harness/session/turn.rs` around lines 923 - 924, The
debug log currently printing the full system prompt body (rendered_prompt.text)
can leak PROFILE/MEMORY contents when include_profile or include_memory_md are
enabled; change the logging around where rendered_prompt.text is emitted to omit
or redact sensitive content whenever include_profile == true or
include_memory_md == true (or omit_profile/omit_memory_md are false), e.g.,
replace the full-body log with either a short summary, length-limited snippet,
or a fixed redaction message indicating PROFILE/MEMORY were omitted; update the
log call(s) that reference rendered_prompt.text to check
include_profile/include_memory_md and avoid printing full prompt when those
flags allow injected sensitive data.

Comment thread src/openhuman/context/prompt.rs Outdated
Comment thread src/openhuman/context/prompt.rs
Copy link
Copy Markdown
Contributor

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/openhuman/context/prompt.rs`:
- Around line 845-861: Add dev-oriented trace logging around the PROFILE.md and
MEMORY.md injection flow: in the block that checks options.include_profile and
options.include_memory_md (and inside/in front of inject_workspace_file_capped),
log entry/exit, branch decisions (file gated vs skipped), the target filename
and workspace_dir, whether the file was found or missing, and the resulting
truncation length versus USER_FILE_MAX_CHARS; also surface any filesystem/read
errors returned by inject_workspace_file_capped so callers can see why a file
was skipped or truncated. Ensure logs are at trace/debug level and include
unique context (e.g., "inject_workspace_file_capped PROFILE.md",
"inject_workspace_file_capped MEMORY.md") so they can be filtered independently.
🪄 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

Run ID: 3a30529a-9125-45b8-942c-84944e967c69

📥 Commits

Reviewing files that changed from the base of the PR and between ce60d27 and 0a14ed0.

📒 Files selected for processing (1)
  • src/openhuman/context/prompt.rs

Comment on lines +845 to 861
// 1c. PROFILE.md (onboarding enrichment output) and MEMORY.md
// (archivist-curated long-term memory). Each is gated on its own
// flag and capped at `USER_FILE_MAX_CHARS` (~1000 tokens) so a
// growing on-disk file can't push the system prompt out of the
// cache-friendly prefix range.
//
// KV-cache contract: once these files land in a session's
// rendered prompt the bytes are frozen for the remainder of that
// session. Do not re-read them mid-turn — a byte change breaks
// the backend's automatic prefix cache. Mid-session writes to
// either file are intentionally only visible on the NEXT session.
if options.include_profile {
inject_workspace_file_capped(&mut out, workspace_dir, "PROFILE.md", USER_FILE_MAX_CHARS);
}
if options.include_memory_md {
inject_workspace_file_capped(&mut out, workspace_dir, "MEMORY.md", USER_FILE_MAX_CHARS);
}
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.

🛠️ Refactor suggestion | 🟠 Major

Add debug/trace observability for the new PROFILE/MEMORY injection flow.

The new gating/truncation path does filesystem reads and branch decisions silently, which makes prompt-diff debugging hard when PROFILE.md/MEMORY.md are skipped or truncated.

Proposed logging patch
@@
-    if options.include_profile {
+    tracing::debug!(
+        include_profile = options.include_profile,
+        include_memory_md = options.include_memory_md,
+        "[context::prompt] subagent user-file injection flags"
+    );
+    if options.include_profile {
         inject_workspace_file_capped(&mut out, workspace_dir, "PROFILE.md", USER_FILE_MAX_CHARS);
     }
@@
 fn inject_workspace_file_capped(
@@
 ) {
     let path = workspace_dir.join(filename);
 
     match std::fs::read_to_string(&path) {
         Ok(content) => {
             let trimmed = content.trim();
             if trimmed.is_empty() {
+                tracing::debug!(
+                    file = filename,
+                    "[context::prompt] skipped empty workspace file injection"
+                );
                 return;
             }
             let _ = writeln!(prompt, "### {filename}\n");
             let truncated = if trimmed.chars().count() > max_chars {
+                tracing::debug!(
+                    file = filename,
+                    max_chars,
+                    "[context::prompt] truncating workspace file for prompt injection"
+                );
                 trimmed
                     .char_indices()
                     .nth(max_chars)
                     .map(|(idx, _)| &trimmed[..idx])
                     .unwrap_or(trimmed)
             } else {
                 trimmed
             };
@@
-        Err(_) => {
+        Err(err) => {
+            tracing::debug!(
+                file = filename,
+                error = %err,
+                "[context::prompt] workspace file missing/unreadable; skipping injection"
+            );
             // Keep prompt focused: missing optional identity/bootstrap files should not
             // add noisy placeholders that dilute tool-calling instructions.
         }
     }
 }

As per coding guidelines: “Add substantial, development-oriented logs on new/changed flows; include logs at entry/exit points, branch decisions, external calls, retries/timeouts, state transitions, and error handling paths”.

Also applies to: 1122-1151

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/openhuman/context/prompt.rs` around lines 845 - 861, Add dev-oriented
trace logging around the PROFILE.md and MEMORY.md injection flow: in the block
that checks options.include_profile and options.include_memory_md (and inside/in
front of inject_workspace_file_capped), log entry/exit, branch decisions (file
gated vs skipped), the target filename and workspace_dir, whether the file was
found or missing, and the resulting truncation length versus
USER_FILE_MAX_CHARS; also surface any filesystem/read errors returned by
inject_workspace_file_capped so callers can see why a file was skipped or
truncated. Ensure logs are at trace/debug level and include unique context
(e.g., "inject_workspace_file_capped PROFILE.md", "inject_workspace_file_capped
MEMORY.md") so they can be filtered independently.

…nonicalization

- Improved the `debug-agent-prompts.sh` script to validate and canonicalize the output directory (`OUT_DIR`) before performing any file operations.
- Added checks to reject relative paths and ensure the output directory is an absolute path, preventing potential catastrophic deletions.
- Implemented a `canonicalize` function that uses `realpath` or `readlink` to resolve paths, with a fallback to Python for compatibility on barebones systems.
- Enhanced error handling to provide clear feedback when the output directory cannot be validated or canonicalized.
- Ensured that the script operates on the canonicalized path for all subsequent commands, maintaining consistency and safety.
@senamakel senamakel merged commit 3db06e8 into tinyhumansai:main Apr 14, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant