prompt

package
v0.3.4 Latest Latest
Warning

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

Go to latest
Published: May 31, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package prompt assembles the cache-stable system prompt for the agent.

Cache-stability invariants enforced here:

  1. The static prefix (StaticBase + InstructionFiles) is never allowed to drift mid-session. Updating the binary's BasePromptV1 constant counts as a release-time bump that intentionally invalidates the prompt cache.
  2. Per-turn dynamic context (git status, current date, etc.) is placed AFTER the DynamicContextBoundary marker so it never pollutes the cached prefix.
  3. The boundary marker string itself is a load-bearing constant. Changing it is a release-time bump.

The Build method composes Static prefix → boundary → Dynamic suffix in that exact order. Callers that need only the cached prefix can split on DynamicContextBoundary.

Index

Constants

View Source
const BasePromptV1 = baseSection1Identity + "\n" + baseSection2Tools + "\n" + baseSection3Style

BasePromptV1 is the cache-stable static base prompt. The "V1" suffix is load-bearing: any change to this constant is a release-time bump that intentionally invalidates the DeepSeek prompt cache, so downstream tasks (T-102~T-104) own the final content but the name stays. Compose order matches the section comments above.

View Source
const DynamicContextBoundary = "\n=== DYNAMIC CONTEXT (per-turn, do not cache) ===\n"

DynamicContextBoundary marks the cut between cache-stable static prompt content and per-turn dynamic context. Everything after this string is regenerated on every turn; everything before it must stay byte-stable across the session.

Variables

This section is empty.

Functions

func RenderProjectContext

func RenderProjectContext(p ProjectContext) string

RenderProjectContext renders the dynamic project context (cwd, git status, git diff) as a string. Exported so the agent can append it after a frozen static prefix without re-building the full prompt.

Types

type InstructionFile

type InstructionFile struct {
	Path    string
	Content string
}

InstructionFile is a loaded whitelist instruction file. Content is already truncated by the loader.

func LoadInstructionFiles

func LoadInstructionFiles(cwd, home string) ([]InstructionFile, error)

LoadInstructionFiles scans cwd and home for whitelist files and returns them in priority order (cwd before home; within each base, declaration order). Same base name in both locations: cwd wins, home copy is skipped.

Hard limits:

  • Per file: maxInstructionFileChars (truncated with marker)
  • Total: maxTotalInstructionChars (later files dropped when full)

Safety:

  • Any base name containing "claude" (case-insensitive) is dropped even if a future edit erroneously adds it to the whitelist. CLAUDE.md MUST NOT load.
  • Missing files and read errors return no error — instructions are advisory.

type ProjectContext

type ProjectContext struct {
	CWD          string
	CurrentDate  string
	GitStatus    string
	GitDiff      string
	ActiveBranch string
	OSName       string
	OSVersion    string
	Shell        string
}

ProjectContext is the dynamic per-turn context appended after the DynamicContextBoundary marker. Git fields are refreshed by the agent on each step; the static fields (CWD, OSName, OSVersion, Shell, CurrentDate) are filled once at session start.

func DiscoverProjectContext

func DiscoverProjectContext(cwd string) ProjectContext

DiscoverProjectContext fills the static-per-session fields of a ProjectContext: cwd, current date (UTC), OS name and version, and shell. Git fields are deliberately left empty — they are per-turn and the agent refreshes them via gitctx.

type SystemPromptBuilder

type SystemPromptBuilder struct {
	// StaticBase is the binary-versioned base prompt. Empty falls
	// back to BasePromptV1.
	StaticBase string

	// Instructions is the loaded set of whitelist instruction files
	// (DEEPSEEK.md, AGENTS.md, .deepseek/instructions.md). Session-once.
	Instructions []InstructionFile

	// SkillDirectory is the canonical stable skill directory text, exactly
	// as produced by skills.Store.PromptIndex() / IndexText() — one line per
	// skill in the form
	//
	//	name | short_description | run_mode | version_hash | allowed_tools
	//
	// It is rendered into the static prefix (before the dynamic boundary) so
	// the model-visible bytes carry the body-derived version_hash. Because
	// this is the same text that feeds the epoch's skill-dir hash, a skill
	// body edit moves the prefix and the epoch hash together. Empty → no
	// ## Skills section. Never contains local absolute paths or skill bodies.
	SkillDirectory string

	// Project carries the dynamic per-turn context (git status, date,
	// os). nil disables the dynamic suffix entirely.
	Project *ProjectContext
}

SystemPromptBuilder composes the system prompt from a static base, session-once instruction files, and per-turn project context. Hold one per agent.

func (*SystemPromptBuilder) Build

func (b *SystemPromptBuilder) Build() string

Build returns the assembled system prompt:

<StaticBase>
<rendered instructions> (omitted if no instructions)
<DynamicContextBoundary>
<rendered project context>  (omitted if Project is nil)

The bytes before DynamicContextBoundary must stay identical across turns within one session — cache invariant.

Jump to

Keyboard shortcuts

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