> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Context Files

> Inject markdown context files into your agent's instructions automatically

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.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Context Injection Flow"
        A[📄 AGENTS.md<br/>CLAUDE.md] --> B[🔍 Walk-up Discovery]
        B --> C[🔗 Layer & Merge]
        C --> D[🤖 Enhanced Agent]
    end
    
    classDef file fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef process fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff
    
    classDef agent fill:#8B0000,color:#fff
    classDef tool fill:#189AB4,color:#fff
    class A file
    class B,C process
    class D output
```

## Quick Start

<Steps>
  <Step title="Drop an AGENTS.md in your project root">
    ```markdown theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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
    ```
  </Step>

  <Step title="Run from any subdirectory — instructions load automatically">
    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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")
    ```
  </Step>
</Steps>

***

## 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):

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    subgraph "Discovery Layers (low → high precedence)"
        GLOBAL["🌐 ~/.praisonai/AGENTS.md<br/>(user-global)"]
        ROOT["📁 git root /<br/>AGENTS.md · CLAUDE.md · agents.md · .agents/AGENTS.md"]
        MID["📁 intermediate dirs<br/>(each level)"]
        CWD["📁 cwd /<br/>AGENTS.md · CLAUDE.md · agents.md · .agents/AGENTS.md"]
    end

    GLOBAL --> ROOT --> MID --> CWD --> MERGE["🔗 Concatenate<br/>global → root → cwd"]
    MERGE --> AGENT["🤖 Agent"]

    classDef layer fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef merge fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef agent fill:#10B981,stroke:#7C90A0,color:#fff

    class GLOBAL,ROOT,MID,CWD layer
    class MERGE merge
    class AGENT agent
```

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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Session start"
        A[📁 cwd walk-up] --> B[📄 already_loaded]
    end
    subgraph "During the session"
        C[✍️ Touch packages/foo/main.py] --> D{Walk up}
        D --> E{Dedup vs<br/>already_loaded<br/>+ seen files}
        E --> F{Budget<br/>remaining?}
        F -->|Yes| G[📎 Attach nearest<br/>AGENTS.md / CLAUDE.md]
        F -->|No| H[⏭ Skip]
    end

    classDef upfront fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef touch fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef attach fill:#10B981,stroke:#7C90A0,color:#fff
    classDef skip fill:#189AB4,stroke:#7C90A0,color:#fff

    class A,B upfront
    class C touch
    class D,E,F decision
    class G attach
    class H skip
```

<Steps>
  <Step title="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.
  </Step>

  <Step title="Attach for a single path (stateless)">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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.")
    ```
  </Step>

  <Step title="Attach across many touches (session-scoped)">
    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    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)
            ...
    ```
  </Step>
</Steps>

### Behaviour guarantees

| Guarantee                                                       | Plain language                                                |
| --------------------------------------------------------------- | ------------------------------------------------------------- |
| Subtree file attached only after a file under it is touched     | Nothing loads until the agent opens something in that folder. |
| Files already in the up-front load are not re-attached          | No duplicate rules from what loaded at startup.               |
| A file emitted for one directory is not re-emitted for another  | The same rules file never shows up twice.                     |
| Repeated touches of the same directory hit the cache            | Re-opening a folder costs nothing — no disk re-read.          |
| A sibling directory with no `AGENTS.md` returns an empty string | Empty folders add nothing.                                    |
| Total emitted text is bounded by `max_chars`                    | The attached context can never grow past the budget.          |
| `load_context_files_for_path(...)` is a stateless one-shot      | Use it when you touch a single path.                          |
| Returns `""` when nothing new is found                          | Silent when there is nothing to add.                          |

### When do I need on-demand attachment?

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Q1{"Are all instruction files inside cwd or above it?"}
    Q1 -->|Yes| UPFRONT["✅ Up-front load_context_files is enough<br/>(no attacher)"]
    Q1 -->|No| Q2{"Does the session touch<br/>many files or one?"}
    Q2 -->|One| ONESHOT["🎯 load_context_files_for_path(path)<br/>(stateless helper)"]
    Q2 -->|Many| CLASS["🔁 PathContextAttacher(...)<br/>(session-scoped cache + dedup)"]

    classDef q fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef pick fill:#10B981,stroke:#7C90A0,color:#fff

    class Q1,Q2 q
    class UPFRONT,ONESHOT,CLASS pick
```

<Note>
  `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.
</Note>

***

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant User
    participant CLI as praisonai CLI
    participant Loader as load_context_files
    participant Agent as Agent backstory

    User->>CLI: praisonai chat / run / code / tui
    CLI->>Loader: walk_up=True, cwd=workspace
    Loader-->>CLI: merged context (≤8000 chars)
    CLI->>Agent: prepend "# Project Context\n{context}"
    Agent-->>User: response with project awareness

    classDef user fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef cli fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef loader fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef agent fill:#10B981,stroke:#7C90A0,color:#fff

    class User user
    class CLI cli
    class Loader loader
    class Agent agent
```

### Opt-out

<Steps>
  <Step title="CLI flag">
    Pass `--no-context` to any of the four commands to skip all project-context loading for that invocation:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    praisonai chat --no-context
    praisonai run --no-context "Quick one-off task"
    praisonai code --no-context
    ```
  </Step>

  <Step title="Environment variable">
    Set `PRAISON_NO_CONTEXT=true` in your shell or CI environment to disable auto-loading globally:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    export PRAISON_NO_CONTEXT=true
    praisonai run "task"   # context skipped
    ```
  </Step>

  <Step title="InteractiveConfig field">
    When using the interactive core programmatically:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.cli.interactive.config import InteractiveConfig

    config = InteractiveConfig(no_context=True)
    ```
  </Step>

  <Step title="configure_host() param">
    In host integrations, pass `no_context=True` directly or via `agent_kwargs` for backward compatibility:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    configure_host(no_context=True)
    # or
    configure_host(agent_kwargs={"no_context": True})
    ```
  </Step>
</Steps>

### Opt-out matrix

| Surface                   | Opt-out                                                    |
| ------------------------- | ---------------------------------------------------------- |
| CLI flag                  | `--no-context`                                             |
| Env var                   | `PRAISON_NO_CONTEXT=true`                                  |
| `InteractiveConfig` field | `no_context=True`                                          |
| `configure_host()` param  | `no_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

<Note>
  Discovery runs once per session and the result is cached. Editing `AGENTS.md` mid-session requires restarting the CLI to pick up changes.
</Note>

***

## Configuration Options

### Default File Discovery

When no `context_paths` is given, these filenames are checked at every directory level:

| Path                | Description                                       |
| ------------------- | ------------------------------------------------- |
| `CLAUDE.local.md`   | Local overrides (highest precedence, git-ignored) |
| `AGENTS.md`         | Primary agent context file (Codex CLI compatible) |
| `agents.md`         | Alternative casing                                |
| `.agents/AGENTS.md` | Hidden directory structure                        |
| `CLAUDE.md`         | Claude Code memory file                           |
| `GEMINI.md`         | Gemini CLI context file                           |

### Discovery Scope

| Layer                            | Location                                               | Precedence                         |
| -------------------------------- | ------------------------------------------------------ | ---------------------------------- |
| User-global                      | `~/.praisonai/AGENTS.md`                               | Lowest (loaded first)              |
| Git/project root                 | Root-level candidates                                  | Low                                |
| Intermediate dirs                | Each dir between root and cwd                          | Medium                             |
| cwd                              | Current working directory candidates                   | Highest (loaded last)              |
| Touched-file subtree (on-demand) | Nearest `AGENTS.md`/`CLAUDE.md` above the touched file | Appended after all up-front layers |

<Note>
  When no git root is found, the walk-up is **capped at 10 levels** to avoid scanning unrelated system directories.
</Note>

### `walk_up` Parameter

| Value              | Behavior                                                      |
| ------------------ | ------------------------------------------------------------- |
| `True` *(default)* | Walk up to git/project root, include `~/.praisonai/AGENTS.md` |
| `False`            | Read 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:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
configure_host(
    context_paths=[
        "docs/guidelines.md",
        "config/style-guide.md", 
        "knowledge/product-info.md"
    ]
)
```

### Choosing a Mode

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    START["Which mode do I need?"] --> Q1{"Explicit file list?"}
    Q1 -->|Yes| EXPLICIT["Pass context_paths=[...]<br/>cwd-only, no walk-up"]
    Q1 -->|No| Q2{"Restrict to cwd only?"}
    Q2 -->|Yes| WALKFALSE["walk_up=False<br/>cwd-only, no global"]
    Q2 -->|No| AUTO["Default auto-discovery<br/>walk_up=True<br/>global → root → cwd"]

    classDef decision fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef choice fill:#10B981,stroke:#7C90A0,color:#fff
    classDef start fill:#6366F1,stroke:#7C90A0,color:#fff

    class START start
    class Q1,Q2 decision
    class EXPLICIT,WALKFALSE,AUTO choice
```

### Context Loading Behavior

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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

```markdown theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# 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):

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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:

```markdown theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# ~/.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

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph BT
    FILE["✍️ packages/foo/main.py"] --> FOO["📄 packages/foo/AGENTS.md"]
    FOO --> ROOT["📁 monorepo/AGENTS.md<br/>(git root)"]

    classDef touch fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef attach fill:#10B981,stroke:#7C90A0,color:#fff
    classDef root fill:#6366F1,stroke:#7C90A0,color:#fff

    class FILE touch
    class FOO attach
    class ROOT root
```

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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

<AccordionGroup>
  <Accordion title="File Organization">
    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
    ```
  </Accordion>

  <Accordion title="Content Structure">
    Keep context files focused and well-organized:

    ```markdown theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # 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
    ```
  </Accordion>

  <Accordion title="When to use walk_up=False">
    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.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    context = load_context_files(walk_up=False)
    ```
  </Accordion>

  <Accordion title="Content Management">
    Version control your context files:

    ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    # Track context changes
    git add AGENTS.md STYLE.md
    git commit -m "Update agent communication guidelines"

    # Review context impact
    git diff HEAD~1 context/
    ```
  </Accordion>

  <Accordion title="Use PathContextAttacher in long-running sessions">
    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.

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.integration.context_files import (
        load_context_files,
        PathContextAttacher,
    )

    up_front = load_context_files()
    attacher = PathContextAttacher(already_loaded=up_front, max_chars=8000)
    ```
  </Accordion>

  <Accordion title="Testing Context Changes">
    Validate context injection in development:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    from praisonai.integration.context_files import load_context_files

    context = load_context_files()
    print("Loaded context length:", len(context))
    print("Preview:", context[:200])
    ```
  </Accordion>
</AccordionGroup>

***

## Related

<CardGroup cols={2}>
  <Card title="Host Integration" icon="plug" href="/docs/features/host-integration">
    Configure context injection
  </Card>

  <Card title="Rules & Instructions" icon="scroll" href="/docs/features/rules">
    Auto-discovered instruction files
  </Card>
</CardGroup>
