# Context files

> How project context files are discovered and injected into sessions, including SDK wiring for context file inputs.

- Repository: earendil-works/pi
- GitHub: https://github.com/earendil-works/pi
- Human docs: https://grok-wiki.com/public/docs/earendil-works-pi-7860a70e44d1
- Complete Markdown: https://grok-wiki.com/public/docs/earendil-works-pi-7860a70e44d1/llms-full.txt

## Source Files

- `packages/coding-agent/examples/sdk/07-context-files.ts`
- `packages/coding-agent/README.md`
- `packages/coding-agent/src/core/agent-session.ts`
- `packages/coding-agent/test/suite/regressions/2860-replaced-session-context.test.ts`
- `packages/coding-agent/examples/sdk/README.md`

---

---
title: "Context files"
description: "How project context files are discovered and injected into sessions, including SDK wiring for context file inputs."
---

Context files in `@earendil-works/pi-coding-agent` are `AGENTS.md` documents: project-specific instructions that `DefaultResourceLoader` discovers from the working directory tree and that sessions load into the system prompt. Discovery and injection are owned by the resource loader; `createAgentSession({ resourceLoader })` wires the loader into `AgentSession`, which is shared across interactive, print, and RPC run modes.

## What counts as a context file

| Term | Meaning in this package |
|------|-------------------------|
| Context file | An `AGENTS.md` entry with `path` and `content` |
| Purpose | Project-specific instructions for the model |
| Injection surface | System prompt (not a user-turn message) |
| Loader API | `DefaultResourceLoader` / `ResourceLoader` |
| Override hook | `agentsFilesOverride` |

Interactive mode surfaces loaded files in the **startup header** alongside prompt templates, skills, and extensions.

## Discovery

`DefaultResourceLoader` discovers `AGENTS.md` files by **walking up from `cwd`**.

```typescript
const loader = new DefaultResourceLoader({
  cwd: process.cwd(),
  agentDir: getAgentDir(),
});
await loader.reload();

const discovered = loader.getAgentsFiles().agentsFiles;
for (const file of discovered) {
  console.log(`  - ${file.path} (${file.content.length} chars)`);
}
```

### Loader construction inputs

| Input | Role |
|-------|------|
| `cwd` | Root of the upward walk for discovery |
| `agentDir` | Agent config directory (via `getAgentDir()` in the SDK example) |
| `agentsFilesOverride` | Optional transform or full replace of the discovered list |
| `reload()` | Must be awaited after construction (and after changing overrides) before reading files |

### Discovered file shape

Each entry in `getAgentsFiles().agentsFiles` exposes at least:

| Field | Type (observed) | Notes |
|-------|-----------------|-------|
| `path` | string | Filesystem path, or a virtual path when injected via override |
| `content` | string | Full file body; length is usable as a size signal |

<Note>
Evidence documents discovery as “walking up from `cwd`” and the `path` / `content` fields only. Stop conditions, merge order across multiple `AGENTS.md` files, and system-prompt formatting details are not specified in the available sources.
</Note>

## Injection into sessions

Context files are not passed as a separate `createAgentSession` option. They flow through the resource loader:

1. Build and `reload()` a `DefaultResourceLoader` (with or without `agentsFilesOverride`).
2. Pass `resourceLoader: loader` into `createAgentSession`.
3. The session uses that loader for extensions, skills, prompts, themes, **context files**, and the system prompt.

```typescript
const { session } = await createAgentSession({
  resourceLoader: loader,
  sessionManager: SessionManager.inMemory(),
});
```

`AgentSessionConfig.resourceLoader` is required and documented as the loader for extensions, skills, prompts, themes, context files, and the system prompt. `AgentSession` is the shared lifecycle layer for interactive, print, and RPC modes; each mode adds its own I/O on top.

### Related loader controls

Context files are orthogonal to other `DefaultResourceLoader` overrides used in the same session setup:

| Override | Effect |
|----------|--------|
| `agentsFilesOverride` | Append, replace, or clear `AGENTS.md` context |
| `systemPromptOverride` | Modify or replace the base system prompt string |
| `skillsOverride` | Control skill discovery |
| `promptsOverride` | Control prompt templates |
| `extensionFactories` | Register extensions |

Disabling discovery and replacing the system prompt are separate knobs. Full-control embeds often set both.

## SDK wiring

### Package surface

Import from `@earendil-works/pi-coding-agent`:

- `createAgentSession`
- `DefaultResourceLoader`
- `getAgentDir`
- `SessionManager`

Reference example: `packages/coding-agent/examples/sdk/07-context-files.ts` (run from the package with `npx tsx examples/sdk/07-context-files.ts`).

### `createAgentSession` options (context-relevant)

| Option | Default | Context-file role |
|--------|---------|-------------------|
| `resourceLoader` | `DefaultResourceLoader` | Owns discovery, overrides, and context-file access |
| `cwd` | `process.cwd()` | Working directory used when the session is created with defaults |
| `agentDir` | `~/.pi/agent` | Config directory for the agent |
| `sessionManager` | `SessionManager.create(cwd)` | Persistence; in-memory is fine for loader-only demos |
| `modelRuntime` | Runtime from `agentDir` auth/models | Not required for loader discovery itself; required for model turns |

### Override patterns

#### Append a virtual context file

Spread discovered files and add an in-memory entry (paths may be virtual):

```typescript
const loader = new DefaultResourceLoader({
  cwd: process.cwd(),
  agentDir: getAgentDir(),
  agentsFilesOverride: (current) => ({
    agentsFiles: [
      ...current.agentsFiles,
      {
        path: "/virtual/AGENTS.md",
        content: `# Project Guidelines

## Code Style
- Use TypeScript strict mode
- No any types
- Prefer const over let`,
      },
    ],
  }),
});
await loader.reload();
```

After reload, `getAgentsFiles().agentsFiles` includes both discovered and virtual entries. The example logs session creation as using `discovered.length + 1` files when one virtual file is appended.

#### Disable context files

Return an empty list from the override (no discovery retained):

```typescript
const resourceLoader = new DefaultResourceLoader({
  systemPromptOverride: () => "You are helpful.",
  agentsFilesOverride: () => ({ agentsFiles: [] }),
  // ...other full-control overrides
});
await resourceLoader.reload();
```

<Warning>
Call `await loader.reload()` after configuring overrides. Reading `getAgentsFiles()` before reload does not apply the configured discovery and override pipeline.
</Warning>

### End-to-end checklist

<Steps>
  <Step title="Construct the loader">
    Pass `cwd`, `agentDir`, and optional `agentsFilesOverride`.
  </Step>
  <Step title="Reload resources">
    `await loader.reload()` so discovery and overrides materialize.
  </Step>
  <Step title="Inspect context files (optional)">
    Read `loader.getAgentsFiles().agentsFiles` and log `path` / `content.length`.
  </Step>
  <Step title="Create the session">
    `await createAgentSession({ resourceLoader: loader, sessionManager, ... })`.
  </Step>
  <Step title="Dispose when finished">
    `session.dispose()` for short-lived SDK scripts.
  </Step>
</Steps>

## Interactive visibility

In interactive mode, the startup header reports **loaded `AGENTS.md` files** (with prompt templates, skills, and extensions). That is the user-visible confirmation that context files were discovered for the current project session.

## Architecture

```text
cwd (walk up)
   │
   ▼
DefaultResourceLoader
   ├─ discover AGENTS.md
   ├─ agentsFilesOverride(current) → { agentsFiles }
   ├─ getAgentsFiles().agentsFiles  → [{ path, content }, ...]
   └─ system prompt (+ other resources)
          │
          ▼
createAgentSession({ resourceLoader })
          │
          ▼
     AgentSession  ── shared by interactive / print / RPC
```

## Constraints and unknowns

| Supported by evidence | Not specified in available evidence |
|----------------------|-------------------------------------|
| Name: `AGENTS.md` | Exact walk stop rules (repo root, filesystem root, etc.) |
| Upward walk from `cwd` | Ordering when multiple `AGENTS.md` files exist |
| `path` + `content` entries | Exact system-prompt wrapping or delimiters |
| Virtual paths via override | Size limits, truncation, or encoding rules |
| Empty override disables files | CLI flags dedicated only to context files |
| Loaded files shown in interactive startup header | Hot-reload of on-disk `AGENTS.md` during a live session |

## Related pages

<CardGroup>
  <Card title="SDK" href="/sdk">
    Embed pi with `createAgentSession`, custom models, tools, and settings.
  </Card>
  <Card title="SDK examples" href="/sdk-examples">
    Copy-paste recipes, including `07-context-files.ts` and full-control setups.
  </Card>
  <Card title="Agent sessions" href="/agent-sessions">
    Session lifecycle and the runtime that owns a conversation turn.
  </Card>
  <Card title="Session runtime" href="/session-runtime">
    `AgentSessionRuntime` services and embedding without the interactive TUI.
  </Card>
  <Card title="Prompt templates" href="/prompt-templates">
    Custom system prompts and reusable prompt configuration.
  </Card>
  <Card title="Run modes" href="/run-modes">
    Interactive, print/JSON, RPC, and SDK modes that share `AgentSession`.
  </Card>
</CardGroup>
