filerefs

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 24, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package filerefs implements the @file reference system: when a user types something like "explain @main.go and @internal/foo.go", the agent detects the @-prefixed tokens, reads the matching files from the working directory, and injects their contents into the system prompt so the model sees the file as authoritative context for the turn — no extra read_file tool call required.

The package is split into three small phases:

  • Parse extracts @<path> tokens from a user message.
  • Load reads each token's file relative to a cwd, with size caps and a strict cwd-confinement check (no symlinks, no traversal).
  • Inject rewrites a system-prompt string by stripping any prior auto-injected section and appending a fresh one for the current turn's refs.

All file-load failures are recorded on the Ref itself (Error field) rather than returned globally — the caller renders them as warnings and still sends the turn. Hard-failing on a missing @file would be frustrating in practice (typos, deleted files, paths inside compound words like "@TODO").

Index

Constants

View Source
const (
	MaxFileSize  = 200 * 1024  // 200 KiB per file
	MaxTotalSize = 1024 * 1024 // 1 MiB total per turn
)

Size caps. Per-file is enforced first; total accumulates as files load and short-circuits the rest once breached. Both are deliberate (small) so the system prompt never balloons.

View Source
const Marker = "## Referenced files (auto-injected from @-prefixed paths)"

Marker is the heading that identifies an auto-injected file-refs block in a system prompt. Inject strips any prior block matching this marker before appending a new one — which keeps the prompt from accumulating stale snapshots across turns.

Variables

This section is empty.

Functions

func BuildSection

func BuildSection(refs []Ref) string

BuildSection formats a slice of Refs into a markdown block ready for injection into the system prompt. Refs whose Loaded is false are emitted as inline error notices so the model sees the failure instead of silently missing a reference. Returns "" when refs is empty so callers can short-circuit "no refs → no injection."

func Inject

func Inject(prompt string, refs []Ref) string

Inject rewrites prompt by stripping any prior auto-injected block and appending a fresh one for the supplied refs. When refs is empty the prompt is returned with the block stripped (so a turn that uses no refs cleans up after one that did).

func Rewrite

func Rewrite(input string, refs []Ref) string

Rewrite returns input with the leading `@` stripped from every successfully-loaded ref's token. Refs that failed to load keep their `@` so the model can ask the user about the typo / missing path explicitly.

Why this exists: without rewriting, the user's message still contains `@docs/foo.md` after we've injected the file's contents into the system prompt. Some models then call `read_file("@docs/foo.md")` — passing the literal `@` to the tool, which fails because the `@` becomes part of the path. Stripping it produces a plain path that pairs naturally with the section we already injected up in the system prompt and removes the failure mode entirely.

func StripSection

func StripSection(prompt string) string

StripSection removes a prior auto-injected file-refs block from a system prompt, returning the prompt with the section excised. Used by Inject so successive turns replace (not accumulate) the block. If no marker is present, prompt is returned unchanged.

Types

type Ref

type Ref struct {
	Token   string // the original "@path" as it appeared in input
	Path    string // the parsed path (without the leading @)
	Loaded  bool
	Content string
	Size    int    // bytes read (post-truncation)
	Error   string // populated when Loaded is false
	IsDir   bool   // true when Path resolves to a directory
}

Ref describes a single @-prefixed reference detected in user input. After Load, exactly one of Loaded or Error is meaningful: Loaded=true + Content populated, or Loaded=false + Error explaining why.

func Load

func Load(refs []Ref, cwd string) []Ref

Load reads each ref's file relative to cwd and fills Content / Error in place. Refs are returned in the same order. The cwd is canonicalized once so symlink/traversal checks compare against a stable root; absolute paths and any path that resolves outside cwd are rejected with a clear Error rather than read.

Size enforcement: a file larger than MaxFileSize is read up to the cap and marked with a "...truncated" note in Content. Once the running total exceeds MaxTotalSize, every remaining ref is rejected with a budget-exhausted Error so the system prompt stays bounded.

func Parse

func Parse(input string) []Ref

Parse scans input for @<path> tokens and returns one Ref per unique path, in first-appearance order. The Token field preserves the original "@path" form for echoing back to the user; Path is the cleaned version Load consumes. Empty input or no matches → nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL