Skip to main content
Context files automatically inject markdown content into your agent’s instructions — drop an AGENTS.md in your project root and every run sees it, no config needed.
from praisonaiagents import Agent

agent = Agent(name="project-agent", instructions="Follow project AGENTS.md guidelines.")
agent.start("Implement the feature using our team conventions.")
The user adds AGENTS.md or CLAUDE.md; discovery merges layered markdown into the agent instructions.

Quick Start

1

Drop an AGENTS.md in your project root

# AGENTS.md
## Company Guidelines
- Always be professional and helpful
- Focus on customer satisfaction
- Use clear, concise language

## Product Information
Our main products include:
- AI Assistant Platform
- Workflow Automation Tools
2

Run from any subdirectory — instructions load automatically

# From the project root
praisonai run "Help a customer"

# Or from a nested package — the root AGENTS.md is still found
cd packages/frontend
praisonai run "Build a login form"
Or use the Python API:
from praisonaiagents import Agent
from praisonai.integration import configure_host

agent = Agent(
    name="Customer Support",
    instructions="Help customers with their questions"
)

# No context_paths needed — auto-discovery picks up AGENTS.md
configure_host(agents=[agent], style="dashboard")

How It Works

load_context_files() walks up from your current directory to the git root, collecting candidates at each level and concatenating them with the nearest file winning (appended last): The merged content is prepended to the agent’s instructions:
{original_instructions}

Context:
{layered_context_from_all_levels}

On-demand Subtree Attachment

On-demand attachment picks up per-subtree AGENTS.md / CLAUDE.md files the up-front walk-up missed, only when a file inside that subtree is actually touched.
1

Zero-config in a monorepo

When your host wires the attacher into the CLI auto-loader, on-demand attachment runs for you — drop a packages/foo/AGENTS.md and it appears the first time the agent edits a file inside packages/foo/. If your host has not wired it in yet, reach for the stateless helper or the session class below.
2

Attach for a single path (stateless)

from praisonaiagents import Agent
from praisonai.integration.context_files import (
    load_context_files,
    load_context_files_for_path,
)

up_front = load_context_files()  # existing walk-up from cwd to root

agent = Agent(
    name="Monorepo Refactorer",
    instructions=up_front + "\n\n" + load_context_files_for_path(
        "packages/foo/main.py",
        already_loaded=up_front,
    ),
)
agent.start("Refactor packages/foo/main.py to use the new logger.")
3

Attach across many touches (session-scoped)

from praisonaiagents import Agent
from praisonai.integration.context_files import (
    load_context_files,
    PathContextAttacher,
)

up_front = load_context_files()
attacher = PathContextAttacher(already_loaded=up_front, max_chars=8000)

for path in ["packages/foo/main.py", "packages/foo/util.py", "packages/bar/api.py"]:
    extra = attacher.attach_for_path(path)
    if extra:
        # feed `extra` into the agent (e.g. via instructions or a system message)
        ...

Behaviour guarantees

GuaranteePlain language
Subtree file attached only after a file under it is touchedNothing loads until the agent opens something in that folder.
Files already in the up-front load are not re-attachedNo duplicate rules from what loaded at startup.
A file emitted for one directory is not re-emitted for anotherThe same rules file never shows up twice.
Repeated touches of the same directory hit the cacheRe-opening a folder costs nothing — no disk re-read.
A sibling directory with no AGENTS.md returns an empty stringEmpty folders add nothing.
Total emitted text is bounded by max_charsThe attached context can never grow past the budget.
load_context_files_for_path(...) is a stateless one-shotUse it when you touch a single path.
Returns "" when nothing new is foundSilent when there is nothing to add.

When do I need on-demand attachment?

PathContextAttacher is session-scoped by design. Create a new instance per session/agent run so cache and dedup state do not leak between users. Not thread-safe.

CLI Auto-loading

As of PraisonAI PR #2358, praisonai chat, praisonai run, praisonai code, and praisonai tui automatically discover and inject AGENTS.md-style project context into the system prompt — no flag required.

Opt-out

1

CLI flag

Pass --no-context to any of the four commands to skip all project-context loading for that invocation:
praisonai chat --no-context
praisonai run --no-context "Quick one-off task"
praisonai code --no-context
2

Environment variable

Set PRAISON_NO_CONTEXT=true in your shell or CI environment to disable auto-loading globally:
export PRAISON_NO_CONTEXT=true
praisonai run "task"   # context skipped
3

InteractiveConfig field

When using the interactive core programmatically:
from praisonai.cli.interactive.config import InteractiveConfig

config = InteractiveConfig(no_context=True)
4

configure_host() param

In host integrations, pass no_context=True directly or via agent_kwargs for backward compatibility:
configure_host(no_context=True)
# or
configure_host(agent_kwargs={"no_context": True})

Opt-out matrix

SurfaceOpt-out
CLI flag--no-context
Env varPRAISON_NO_CONTEXT=true
InteractiveConfig fieldno_context=True
configure_host() paramno_context=True (or agent_kwargs={"no_context": True})

Token budget and truncation

The default budget is 8000 characters. When discovered context exceeds the budget, it is truncated and \n... [project context truncated] is appended. Override via:
  • InteractiveConfig(context_token_budget=16000) for interactive sessions
  • configure_host(context_token_budget=16000) for host integrations
Discovery runs once per session and the result is cached. Editing AGENTS.md mid-session requires restarting the CLI to pick up changes.

Configuration Options

Default File Discovery

When no context_paths is given, these filenames are checked at every directory level:
PathDescription
CLAUDE.local.mdLocal overrides (highest precedence, git-ignored)
AGENTS.mdPrimary agent context file (Codex CLI compatible)
agents.mdAlternative casing
.agents/AGENTS.mdHidden directory structure
CLAUDE.mdClaude Code memory file
GEMINI.mdGemini CLI context file

Discovery Scope

LayerLocationPrecedence
User-global~/.praisonai/AGENTS.mdLowest (loaded first)
Git/project rootRoot-level candidatesLow
Intermediate dirsEach dir between root and cwdMedium
cwdCurrent working directory candidatesHighest (loaded last)
Touched-file subtree (on-demand)Nearest AGENTS.md/CLAUDE.md above the touched fileAppended after all up-front layers
When no git root is found, the walk-up is capped at 10 levels to avoid scanning unrelated system directories.

walk_up Parameter

ValueBehavior
True (default)Walk up to git/project root, include ~/.praisonai/AGENTS.md
FalseRead only from cwd, skip global file
The walk_up parameter is ignored when you pass an explicit paths list.

Explicit Paths (Backward Compatible)

Pass context_paths to skip auto-discovery entirely — files are read from cwd only:
configure_host(
    context_paths=[
        "docs/guidelines.md",
        "config/style-guide.md", 
        "knowledge/product-info.md"
    ]
)

Choosing a Mode

Context Loading Behavior

from praisonai.integration.context_files import load_context_files

# Auto-discovery (default): walks up, includes global file
context = load_context_files()

# Restrict to cwd only (no walk-up, no global)
context = load_context_files(walk_up=False)

# Explicit paths: cwd-only, no walk-up (backward compatible)
context = load_context_files(paths=["AGENTS.md", "STYLE.md"])
De-duplication is automatic: if cwd equals the git root, the same file is read only once (matched by inode, safe on case-insensitive volumes).

File Structure Examples

Basic AGENTS.md

# Agent Context

## Role Definition
You are a customer support specialist with deep knowledge of our products.

## Communication Style
- Be friendly and professional
- Use active voice
- Keep responses under 150 words unless detailed explanation needed

## Knowledge Areas
- Product features and pricing
- Technical troubleshooting
- Account management procedures

Monorepo Layering

Place org-wide guidelines at the repo root and package-specific overrides closer to the working directory:
monorepo/
├── AGENTS.md              # Org-wide guidelines (lowest project precedence)
├── packages/
│   ├── frontend/
│   │   └── AGENTS.md      # Frontend overrides (higher precedence)
│   └── backend/
│       └── AGENTS.md      # Backend overrides (higher precedence)
Running from inside packages/frontend/ automatically merges both files — root guidelines first, frontend overrides last (winning):
cd packages/frontend
praisonai run "Add a login form"
# Loads: monorepo/AGENTS.md → packages/frontend/AGENTS.md
No context_paths configuration needed.

User-Global Instructions

~/.praisonai/AGENTS.md applies across all your projects as the lowest-priority layer:
# ~/.praisonai/AGENTS.md
## Personal Preferences
- Always respond in British English
- Prefer async/await over callbacks
- Include type hints in all Python code
Every project you work in inherits these preferences unless overridden by a project-level file.

Common Patterns

Environment-Specific Context

import os
from praisonaiagents import Agent
from praisonai.integration import configure_host

agent = Agent(name="Assistant", instructions="You are helpful.")

env = os.getenv("ENVIRONMENT", "development")
context_files = ["AGENTS.md"]

if env == "production":
    context_files.append("production-guidelines.md")
else:
    context_files.append("dev-guidelines.md")

configure_host(agents=[agent], context_paths=context_files)

Monorepo with sibling subtrees

Start a session at the repo root, then let the agent open files in different packages — each package’s own AGENTS.md attaches the moment the agent touches a file there.
monorepo/
├── AGENTS.md                    # Org-wide guidelines
└── packages/
    ├── foo/
    │   ├── AGENTS.md            # Foo conventions
    │   └── main.py
    └── bar/
        ├── AGENTS.md            # Bar conventions
        └── api.py
from praisonai.integration.context_files import (
    load_context_files,
    PathContextAttacher,
)

up_front = load_context_files()  # session starts at the repo root
attacher = PathContextAttacher(already_loaded=up_front)

attacher.attach_for_path("packages/foo/main.py")  # attaches packages/foo/AGENTS.md
attacher.attach_for_path("packages/bar/api.py")   # attaches packages/bar/AGENTS.md
attacher.attach_for_path("packages/foo/util.py")  # cached — no disk re-read, nothing new
The agent picks up each package’s conventions the moment it opens a file there.

Conditional Context Loading

def get_context_files(agent_type):
    base_files = ["AGENTS.md"]
    
    if agent_type == "support":
        base_files.append("support-protocols.md")
    elif agent_type == "sales":
        base_files.append("sales-playbook.md")
    
    return base_files

configure_host(context_paths=get_context_files("support"))

CI / Snapshot Testing

When you don’t want ancestor files to influence a test run, disable walk-up:
from praisonai.integration.context_files import load_context_files

# Only reads files in the current test directory
context = load_context_files(walk_up=False)

Best Practices

Structure your context files for maintainability:
context/
├── base/
│   ├── guidelines.md     # Universal principles
│   └── style.md         # Communication style
├── roles/
│   ├── support.md       # Role-specific context
│   └── sales.md         # Role-specific context  
└── knowledge/
    ├── products.md      # Product information
    └── policies.md      # Company policies
Keep context files focused and well-organized:
# Context File Template

## Core Role
Brief description of the agent's primary function

## Guidelines  
- Key behavioral guidelines
- Communication principles
- Quality standards

## Knowledge Areas
Relevant domain knowledge the agent should reference

## Examples
Sample interactions or responses when helpful
Disable walk-up for isolated CI jobs, snapshot tests, or any run where you want to guarantee only the files in the current directory are loaded — no ancestor directories, no global user file.
context = load_context_files(walk_up=False)
Version control your context files:
# Track context changes
git add AGENTS.md STYLE.md
git commit -m "Update agent communication guidelines"

# Review context impact
git diff HEAD~1 context/
When the agent will touch many files across a monorepo, create one PathContextAttacher per session and reuse it. The per-directory cache means repeated touches of the same subtree cost nothing, and the char budget stops the attached context from growing unbounded across the run. Pass already_loaded=up_front (the string returned by load_context_files()) so files discovered up front are not re-attached.
from praisonai.integration.context_files import (
    load_context_files,
    PathContextAttacher,
)

up_front = load_context_files()
attacher = PathContextAttacher(already_loaded=up_front, max_chars=8000)
Validate context injection in development:
from praisonai.integration.context_files import load_context_files

context = load_context_files()
print("Loaded context length:", len(context))
print("Preview:", context[:200])

Host Integration

Configure context injection

Rules & Instructions

Auto-discovered instruction files