bruteSourceBruteSystemPrompt

class SystemPrompt

Deferred system prompt builder.

The block passed to +build+ is stored — not executed — until +prepare+ is called with a runtime context hash (provider_name, model_name, cwd, etc).

sp = Brute::SystemPrompt.build do |prompt, ctx| prompt.append Brute::Prompts::Identity.call(ctx) prompt.append Brute::Prompts::ToneAndStyle.call(ctx) prompt.append Brute::Prompts::Environment.call(ctx) end

result = sp.prepare(provider_name: "anthropic", model_name: "claude-sonnet-4-20250514", cwd: Dir.pwd) result.to_s # single joined string result.sections # array of strings (one per p.system call)

Definitions

def self.build(&block)

Build a deferred system prompt. The block is stored and called later by +prepare+.

Implementation

def self.build(&block)
  new(block)
end

def self.default

Return the default system prompt. Selects the right provider stack at prepare-time, then appends conditional sections based on runtime state.

Implementation

def self.default
  build do |prompt, ctx|
    # Provider-specific base stack.
    # For gateway providers (opencode_zen, opencode_go), infer the
    # upstream model family from the model name so we use the most
    # appropriate prompt stack (e.g., anthropic stack for claude-*).
    provider = ctx[:provider_name].to_s
    stack_key = if provider.start_with?("opencode")
                  infer_stack_from_model(ctx[:model_name].to_s)
                else
                  provider
                end
    STACKS.fetch(stack_key, STACKS["default"]).each do |mod|
      prompt << mod.call(ctx)
    end

    # Conditional: agent-specific reminders
    if ctx[:agent] == "plan"
      prompt << Prompts::PlanReminder.call(ctx)
    end

    if ctx[:agent_switched] == "build"
      prompt << Prompts::BuildSwitch.call(ctx)
    end

    if ctx[:max_steps_reached]
      prompt << Prompts::MaxSteps.call(ctx)
    end
  end
end

STACKS

Pre-configured prompt stacks per provider. Each maps a provider name to an ordered list of prompt modules.

Implementation

STACKS = {
  # Claude — full-featured with task management and detailed tool policy
  "anthropic" => [
    Prompts::Identity,
    Prompts::ToneAndStyle,
    Prompts::Objectivity,
    Prompts::TaskManagement,
    Prompts::DoingTasks,
    Prompts::ToolUsage,
    Prompts::Conventions,
    Prompts::GitSafety,
    Prompts::CodeReferences,
    Prompts::Environment,
    Prompts::Skills,
    Prompts::Instructions,
  ],

  # GPT-4 / o1 / o3 — pragmatic engineer persona, editing focus, autonomy
  "openai" => [
    Prompts::Identity,
    Prompts::EditingApproach,
    Prompts::Autonomy,
    Prompts::EditingConstraints,
    Prompts::FrontendTasks,
    Prompts::ToneAndStyle,
    Prompts::Conventions,
    Prompts::GitSafety,
    Prompts::CodeReferences,
    Prompts::Environment,
    Prompts::Skills,
    Prompts::Instructions,
  ],

  # Gemini — formal/structured, explicit workflows, security focus
  "google" => [
    Prompts::Identity,
    Prompts::Conventions,
    Prompts::DoingTasks,
    Prompts::ToneAndStyle,
    Prompts::SecurityAndSafety,
    Prompts::ToolUsage,
    Prompts::GitSafety,
    Prompts::CodeReferences,
    Prompts::Environment,
    Prompts::Skills,
    Prompts::Instructions,
  ],

  # Ollama — lean stack for local models with smaller context windows
  "ollama" => [
    Prompts::Identity,
    Prompts::ToneAndStyle,
    Prompts::Conventions,
    Prompts::DoingTasks,
    Prompts::ToolUsage,
    Prompts::GitSafety,
    Prompts::Environment,
    Prompts::Instructions,
  ],

  # Fallback — conservative, concise, fewer than 4 lines
  "default" => [
    Prompts::Identity,
    Prompts::ToneAndStyle,
    Prompts::Proactiveness,
    Prompts::Conventions,
    Prompts::CodeStyle,
    Prompts::DoingTasks,
    Prompts::ToolUsage,
    Prompts::GitSafety,
    Prompts::CodeReferences,
    Prompts::Environment,
    Prompts::Skills,
    Prompts::Instructions,
  ],
}.freeze

def self.infer_stack_from_model(model_name)

Infer the best prompt stack from a model name. Used for gateway providers that route to multiple upstream model families.

Implementation

def self.infer_stack_from_model(model_name)
  case model_name
  when /\bclaude\b/i, /\bbig.?pickle\b/i
    "anthropic"
  when /\bgpt\b/i, /\bo[134]\b/i, /\bcodex\b/i
    "openai"
  when /\bgemini\b/i, /\bgemma\b/i
    "google"
  else
    "default"
  end
end

def prepare(ctx)

Execute the stored block with the given context and return a Result.

Implementation

def prepare(ctx)
  sections = []
  @block.call(sections, ctx)
  Result.new(sections.compact.reject { |s| s.respond_to?(:empty?) && s.empty? })
end

Result

Immutable result of a prepared system prompt.

Implementation

Result = Struct.new(:sections) do
  def to_s
    sections.join("\n\n")
  end

  def each(&block)
    sections.each(&block)
  end

  def empty?
    sections.empty?
  end
end