Repository navigation
feat(prompts): load AGENTS.md project instructions into the system prompt - #5087
Conversation
Loads configurable instruction text from AGENTS.md files at a global (<workspace_dir>) and local/project (<action_dir>) layer, with dedupe when both dirs resolve to the same path. Missing/unreadable/empty files are silently skipped. Pure functions returning pre-loaded strings so the prompt sections stay testable and the frozen-prefix contract holds.
Add agents_md_global/agents_md_local to PromptContext, a shared write_agents_md_blocks helper, the AgentsInstructionsSection (rendered as '## Project instructions (AGENTS.md)', global then local, each capped at BOOTSTRAP_MAX_CHARS with a truncation marker), and register it after user files and before the tool catalogue in both with_defaults() and for_subagent(). All existing PromptContext literals updated to pass None/None (feature off until wired at the load sites). Covered by section + builder-registration + truncation + ordering tests.
Default-on bool (serde default) that gates AGENTS.md loading/injection. Off means no AGENTS.md content is loaded. Covered by default + serde round-trip tests.
Main agent (session/turn/context.rs): load global (<workspace_dir>) + local (<action_dir>) layers once at build_system_prompt, gated by agents_md_enabled. Subagent runner: load global + project layers, where the project layer is the worktree_action_dir override when set else the config action_dir; thread through both the Dynamic (PromptContext) and Inline/File (render_subagent_system_prompt_with_format) paths. The narrow renderer gained agents_md params and emits the shared block after user files, before the tool catalogue. Covered by subagent-renderer tests.
Add an intelligence.agents_md_instructions capability to the about_app catalog and an AGENTS.md subsection to the agent-harness architecture doc covering the global/project layers, dedupe, caps, and the config gate.
Prevent rare temp-dir collisions when the loader tests run in parallel (same pid + nanosecond timestamp).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5f3fb643d8
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 2 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds configurable two-layer ChangesAGENTS.md instruction injection
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Agent
participant AGENTSLoader
participant PromptContext
participant PromptRenderer
Agent->>AGENTSLoader: Load workspace and project AGENTS.md layers
AGENTSLoader-->>Agent: Return deduplicated optional content
Agent->>PromptContext: Store global and local instructions
PromptContext->>PromptRenderer: Render instructions after user files
PromptRenderer-->>Agent: Produce system prompt before tools
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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/about_app/catalog_data.rs`:
- Around line 405-423: Update the AGENTS.md capability’s privacy classification
from LOCAL_RAW to the provider-dependent raw-egress classification used for
content included in configured cloud-model prompts. Keep the capability behavior
and description unchanged, and ensure the privacy surface reflects that raw
instructions may leave the device when remote providers are enabled.
In `@src/openhuman/agent/harness/session/turn/context.rs`:
- Around line 291-306: Update the shared load_agents_md loader to cap each
trimmed AGENTS.md layer at 20,000 characters and append the established
truncation marker when content exceeds the cap, before constructing
AgentsMdContent. Apply this root-cause fix for both
src/openhuman/agent/harness/session/turn/context.rs:291-306 and
src/openhuman/agent/harness/subagent_runner/ops/runner.rs:973-1003; keep both
callers unchanged so primary and sub-agent prompts use the bounded loader.
In `@src/openhuman/agent/prompts/agents_md.rs`:
- Around line 53-67: Bound AGENTS.md loading in load_agents_md to the documented
20,000-character limit before allocating the full file, preserving valid UTF-8
and existing empty-content handling. In src/openhuman/agent/prompts/agents_md.rs
lines 53-67, enforce the limit at read time; in
src/openhuman/agent/prompts/mod_tests.rs lines 2035-2050, add an oversized
AGENTS.md fixture and assert load_agents_md returns bounded content before
rendering.
In `@src/openhuman/tinyagents/payload_summarizer.rs`:
- Around line 334-335: Update the SubAgent construction in
build_tinyagents_system_prompt so agents_md_global and agents_md_local receive
the effective AGENTS.md instruction layers, including the worktree action
directory when available, allowing AgentsInstructionsSection to render them. If
this summarizer is intentionally excluded from sub-agent injection, document
that contract and add a regression 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: 7951a8d5-2d44-4f8a-b3b8-09b04e354d48
📒 Files selected for processing (50)
gitbooks/developing/architecture/agent-harness.mdsrc/openhuman/about_app/catalog_data.rssrc/openhuman/agent/debug/mod.rssrc/openhuman/agent/harness/session/turn/context.rssrc/openhuman/agent/harness/subagent_runner/ops/runner.rssrc/openhuman/agent/prompts/agents_md.rssrc/openhuman/agent/prompts/builder.rssrc/openhuman/agent/prompts/mod.rssrc/openhuman/agent/prompts/mod_tests.rssrc/openhuman/agent/prompts/render_helpers.rssrc/openhuman/agent/prompts/sections.rssrc/openhuman/agent/prompts/types.rssrc/openhuman/agent/triage/evaluator.rssrc/openhuman/agent_registry/agents/archivist/prompt.rssrc/openhuman/agent_registry/agents/code_executor/prompt.rssrc/openhuman/agent_registry/agents/context_scout/prompt.rssrc/openhuman/agent_registry/agents/critic/prompt.rssrc/openhuman/agent_registry/agents/crypto_agent/prompt.rssrc/openhuman/agent_registry/agents/desktop_control_agent/prompt.rssrc/openhuman/agent_registry/agents/goals_agent/prompt.rssrc/openhuman/agent_registry/agents/help/prompt.rssrc/openhuman/agent_registry/agents/image_agent/prompt.rssrc/openhuman/agent_registry/agents/integrations_agent/prompt.rssrc/openhuman/agent_registry/agents/loader.rssrc/openhuman/agent_registry/agents/markets_agent/prompt.rssrc/openhuman/agent_registry/agents/mcp_agent/prompt.rssrc/openhuman/agent_registry/agents/mcp_setup/prompt.rssrc/openhuman/agent_registry/agents/morning_briefing/prompt.rssrc/openhuman/agent_registry/agents/orchestrator/prompt.rssrc/openhuman/agent_registry/agents/planner/prompt.rssrc/openhuman/agent_registry/agents/presentation_agent/prompt.rssrc/openhuman/agent_registry/agents/researcher/prompt.rssrc/openhuman/agent_registry/agents/scheduler_agent/prompt.rssrc/openhuman/agent_registry/agents/skill_creator/prompt.rssrc/openhuman/agent_registry/agents/summarizer/prompt.rssrc/openhuman/agent_registry/agents/task_manager_agent/prompt.rssrc/openhuman/agent_registry/agents/tool_maker/prompt.rssrc/openhuman/agent_registry/agents/tools_agent/prompt.rssrc/openhuman/agent_registry/agents/trigger_reactor/prompt.rssrc/openhuman/agent_registry/agents/trigger_triage/prompt.rssrc/openhuman/agent_registry/agents/video_agent/prompt.rssrc/openhuman/agent_registry/agents/vision_agent/prompt.rssrc/openhuman/config/schema/agent.rssrc/openhuman/flows/agents/flow_discovery/prompt.rssrc/openhuman/flows/agents/workflow_builder/prompt.rssrc/openhuman/learning/prompt_sections.rssrc/openhuman/memory_tools/prompt.rssrc/openhuman/profiles/prompt_section.rssrc/openhuman/tinyagents/payload_summarizer.rssrc/openhuman/tinyplace/agent/prompt.rs
Dynamic agents (PromptSource::Dynamic) assemble their own body via render_* helpers and none call render_agents_md, so the pre-loaded AGENTS.md layers were silently dropped for the primary/orchestrator (main chat) agent. Inject AgentsInstructionsSection centrally in from_dynamic — mirroring how build() appends the grounding contract — so every dynamic agent inherits the same AGENTS.md injection as the with_defaults / for_subagent chains. Regression test + doc update.
load_agents_md used read_to_string, slurping an arbitrarily large untrusted project file whole before the renderer's char cap. Open + take() a byte bound (BOOTSTRAP_MAX_CHARS*4 + slack) so a pathological multi-MB AGENTS.md can't stall prompt construction or exhaust memory; render-time cap + truncation marker still fire unchanged for well-formed files. Adds bounded-read test.
AGENTS.md raw content is injected into the system prompt sent to the configured inference provider, so it leaves the device when a remote provider is active. LOCAL_RAW (leaves_device: false) under-reported this; classify as raw egress to the configured inference provider.
The internal payload summarizer intentionally omits AGENTS.md layers: it does no project work and builds its prompt directly (outside from_dynamic), so it is deliberately outside the injection contract. Document the contract in-code.
There was a problem hiding this comment.
💡 Codex Review
openhuman/src/openhuman/agent/harness/subagent_runner/ops/runner.rs
Lines 1028 to 1029 in de06909
When a spawned child uses a built-in dynamic prompt, the new AGENTS.md layers are put on prompt_ctx but never rendered: built-ins are stamped as PromptSource::Dynamic in agent_registry/agents/loader.rs:435, and this branch calls build(&prompt_ctx) directly instead of going through SystemPromptBuilder::from_dynamic or render_subagent_system_prompt_with_format, the only paths that emit AgentsInstructionsSection. Fresh evidence in this revision is that lines 979-986 now load the subagent layers, but this dynamic branch still bypasses both renderers, so delegates like code_executor/researcher ignore project instructions while Inline/File subagents get them.
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
AGENTS.mdinstruction files and injects them into the agent system prompt, analogous to Claude Code'sCLAUDE.md/ Codex'sAGENTS.md.<workspace_dir>/AGENTS.md(next toSOUL.md/USER.md) and a local<action_dir>/AGENTS.mdfrom the folder the agent operates in; global renders first, local layered after.worktree_action_diroverride) for the local layer.agents_md_enabledconfig gate onAgentConfig(default on); each file capped at 20k chars with a truncation marker; loaded once per prompt build so the frozen system-prompt prefix / KV-cache contract is preserved.Problem
Solution
src/openhuman/agent/prompts/agents_md.rs(load_agents_md/load_agents_md_layers): silent skip on missing/unreadable/empty, dedupe when global and local dirs canonicalize to the same path,[agents_md]debug logging.agents_md_global/agents_md_localfields onPromptContext(mirrors the existingpersonality_soul_mdinline-content pattern), rendered by a newAgentsInstructionsSection(## Project instructions (AGENTS.md)) registered in bothSystemPromptBuilder::with_defaults()andfor_subagent(); a sharedwrite_agents_md_blockshelper keeps the section and the narrow subagent renderer from drifting.session/turn/context.rs::build_system_prompt(global=workspace_dir, local=action_dir); subagent runner threads it through both the Dynamic (PromptContext) and Inline/File render paths, honouringworktree_action_dir.Submission Checklist
agent::prompts66 passed,config::schema::agent14 passed,subagent_runner80 passed,about_app30 passed)docs/TEST-COVERAGE-MATRIX.md; prompt-assembly behaviour addition covered by unit tests## Related— no matrix rows affectedCloses #NNN— no tracking issue; feature requested directlyImpact
AGENTS.md; no behaviour change when the files are absent oragents_md_enabled = false.Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
Validation Run
pnpm --filter openhuman-app format:check— no frontend changes;cargo fmt --checkcleanpnpm typecheck— no TypeScript changescargo test --lib agent::prompts(66 passed),config::schema::agent(14 passed),subagent_runner(80 passed),about_app(30 passed)GGML_NATIVE=OFF cargo checkclean,cargo fmt --checkcleanapp/src-tauriuntouchedValidation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
Duplicate / Superseded PR Handling
Summary by CodeRabbit
New Features
AGENTS.mdfiles into agent prompts.Documentation