Skip to content

Latest commit

 

History

History
743 lines (560 loc) · 16.1 KB

File metadata and controls

743 lines (560 loc) · 16.1 KB

API Reference

Complete reference for Repatch's tools, steps, and core interfaces.


Table of Contents

  1. Tools
  2. Orchestrator Steps
  3. Core Interfaces
  4. Inference Providers
  5. Sandbox Execution
  6. Configuration

Tools

All tools are defined in src/tools/registry.ts and registered with Zod schemas for validation.

Tool Interface

interface Tool {
  name: string;
  description: string;
  parameters: Record<string, unknown>; // Zod schema
  handler: (args: any) => Promise<any>;
}

Available Tools

Tool Steps Available Description
list_files UNDERSTAND, EXPLORE, REPRODUCE, PLAN, VERIFY List files recursively
read_file EXPLORE, REPRODUCE, PLAN, EXECUTE, VERIFY, SUBMIT Read file with line numbers
grep_search EXPLORE, REPRODUCE, PLAN Search pattern in files
run_command REPRODUCE, VERIFY, SUBMIT Run command in Docker sandbox
run_local_command REPRODUCE, VERIFY, SUBMIT Run command locally (Nixpacks)
write_file EXECUTE Create/overwrite file
edit_file EXECUTE Surgical snippet replacement
create_reproduction_test REPRODUCE Create dedicated test file

list_files

Purpose: List files in a directory recursively with optional pattern filter.

Parameters:

{
  "dirPath": "string (required)",
  "pattern": "string (optional, glob pattern)"
}

Returns: FileResult[]

interface FileResult {
  path: string;
  isDirectory: boolean;
  size?: number;
}

Example:

{ "dirPath": "/repo", "pattern": "*.ts" }

read_file

Purpose: Read a file and return content with line numbers.

Parameters:

{
  "filePath": "string (required)"
}

Returns: FileResult

interface FileResult {
  path: string;
  content: string;
  lineCount: number;
}

Example:

{ "filePath": "/repo/src/auth.ts" }

grep_search

Purpose: Search for a pattern in files within a directory.

Parameters:

{
  "pattern": "string (required)",
  "dirPath": "string (required)",
  "extensions": "string[] (optional)"
}

Returns: GrepResult[]

interface GrepResult {
  file: string;
  line: number;
  match: string;
  context: string; // surrounding lines
}

Example:

{ "pattern": "authenticate", "dirPath": "/repo/src", "extensions": [".ts", ".js"] }

run_command

Purpose: Execute a command inside a Docker sandbox container.

Parameters:

{
  "imageTag": "string (required)",
  "cmd": "string (required)",
  "repoPath": "string (optional)"
}

Returns: CommandResult

interface CommandResult {
  stdout: string;
  stderr: string;
  exitCode: number;
}

Example:

{
  "imageTag": "repatch-sandbox:abc123",
  "cmd": "npm test",
  "repoPath": "/repo"
}

run_local_command

Purpose: Execute a command locally using Nixpacks-detected environment.

Parameters:

{
  "cmd": "string (required)",
  "repoPath": "string (required)"
}

Returns: CommandResult

Example:

{ "cmd": "npm test", "repoPath": "/repo" }

write_file

Purpose: Create or overwrite a file with content.

Parameters:

{
  "filePath": "string (required)",
  "content": "string (required)"
}

Returns:

{ "success": true, "path": "string" }

Example:

{
  "filePath": "/repo/src/new-file.ts",
  "content": "export function hello() { return 'world'; }"
}

edit_file

Purpose: Surgically replace a code snippet using fuzzy matching.

Parameters:

{
  "filePath": "string (required)",
  "oldSnippet": "string (required)",
  "newSnippet": "string (required)"
}

Returns:

{ "success": true, "path": "string" }

Matching Algorithm:

  1. Exact match (whitespace-normalized)
  2. Sliding window search (±5 lines)
  3. Token-based similarity (if enabled)

Example:

{
  "filePath": "/repo/src/auth.ts",
  "oldSnippet": "if (user.email === '') { return false; }",
  "newSnippet": "if (!user.email || user.email === '') { return false; }"
}

create_reproduction_test

Purpose: Create a dedicated test file to reproduce a bug.

Parameters:

{
  "dirPath": "string (required)",
  "content": "string (required)",
  "fileName": "string (optional, default: 'reproduce.test.ts')"
}

Returns:

{ "success": true, "path": "string" }

Example:

{
  "dirPath": "/repo/tests",
  "content": "import { authenticate } from '../src/auth';\ntest('empty email fails', () => { expect(authenticate('', 'pass')).toBe(false); });",
  "fileName": "auth-reproduction.test.ts"
}

Orchestrator Steps

All steps are in src/orchestrator/steps/ and implement the BaseStep interface.

Step Interface

interface BaseStep {
  readonly name: Step;  // "UNDERSTAND" | "EXPLORE" | "REPRODUCE" | "PLAN" | "EXECUTE" | "VERIFY" | "SUBMIT"
  execute(state: AgentState): Promise<StepResult>;
}

interface StepResult {
  nextStep: Step;
  state: AgentState;
  cost?: number;
}

interface StepDependencies {
  model: string;
  maxIterations: number;
  isLocal?: boolean;
  sandboxImageTag?: string;
  executeTool(toolCall: ToolCall, state: AgentState): Promise<unknown>;
  onLLMResponse?(response: LLMResponse): void;
}

UNDERSTAND

File: src/orchestrator/steps/understand.ts

Purpose: Analyze issue, build context, identify keywords and references.

Tools: list_files

Input State: issueText, repoUrl, hint?

Output State: fileTree, references?, history entry

Prompt Template:

You are a Senior Software Engineer triaging a bug report.
REPO: {repoUrl}
ISSUE: {issueText}
MAP OF TRUTH (File Tree): {fileTree}

Task:
1. Summarize the bug with technical precision
2. Identify authoritative source (MDN, Unicode, Wikipedia, etc.)
3. Determine keywords and likely files

Respond with JSON:
{"summary": "...", "references": ["url1"], "keywords": [...], "analysis": "..."}

EXPLORE

File: src/orchestrator/steps/explore.ts

Purpose: LLM-guided search for relevant files using grep/read.

Tools: list_files, read_file, grep_search

Input State: issueText, fileTree, visitedFiles, hint?, keywords?

Output State: visitedFiles (updated), history entry

Behavior:

  • Iterative: LLM calls tools until satisfied or max iterations
  • Tracks visited files to avoid re-reading
  • Parallel batching for multiple grep searches

REPRODUCE

File: src/orchestrator/steps/reproduce.ts

Purpose: Generate minimal failing test that proves the bug exists.

Tools: list_files, read_file, grep_search, run_command, create_reproduction_test

Input State: issueText, visitedFiles, fileTree, hint?

Output State: reproductionTest, reproductionFailureOutput, history entry

Behavior:

  • Writes test file via create_reproduction_test
  • Runs test via run_command/run_local_command
  • Captures failure output for PLAN step
  • Falls back to EXPLORE if no reproduction found

PLAN

File: src/orchestrator/steps/plan.ts

Purpose: Create surgical fix plan with line-level changes.

Tools: list_files, read_file, grep_search

Input State: issueText, visitedFiles, reproductionFailureOutput, fileTree, hint?

Output State: fixPatch (JSON plan), history entry

Prompt Template:

You are a Senior Engineer planning a fix.
ISSUE: {issueText}
REPRODUCTION FAILURE: {reproductionFailureOutput}
VISITED FILES: {visitedFiles}
MAP OF TRUTH: {fileTree}

Create a fix plan with:
{
  "rootCause": "...",
  "changes": [
    {"file": "path", "oldSnippet": "...", "newSnippet": "..."}
  ],
  "testStrategy": "..."
}

EXECUTE

File: src/orchestrator/steps/execute.ts

Purpose: Apply fixes using fuzzy surgical matching.

Tools: read_file, edit_file, write_file

Input State: fixPatch, visitedFiles

Output State: history entry, errorLogs (if any)

Behavior:

  • Iterates through fixPatch.changes
  • Uses fuzzy matching (exact → sliding window → token similarity)
  • Logs each edit attempt
  • Backtracks to PLAN on failure

VERIFY

File: src/orchestrator/steps/verify.ts

Purpose: Run tests + linters in sandbox to confirm fix works.

Tools: run_command, list_files

Input State: repoPath, sandboxImageTag, isLocal, fixPatch

Output State: verificationSuccessOutput, lintOutput, history entry

Behavior:

  1. Detects test command (package.json, pyproject.toml, etc.)
  2. Runs tests in sandbox
  3. Runs linter if configured
  4. Backtracks to PLAN on test/lint failure (max 2 retries)

SUBMIT

File: src/orchestrator/steps/submit.ts

Purpose: Open PR with fix and engineering narrative.

Tools: read_file, run_command

Input State: All previous state

Output State: prUrl (in result), history entry

Behavior:

  • Generates branch name: repatch/fix-{issueHash}
  • Creates commit with conventional message
  • Pushes to fork/remote
  • Opens PR via GitHub API
  • Includes engineering narrative in PR body

Core Interfaces

AgentState

interface AgentState {
  currentStep: Step;
  repoUrl: string;
  issueUrl: string;
  issueText: string;
  repoPath: string;
  fileTree?: string;
  monologue?: string;
  visitedFiles: string[];
  reproductionTest?: string;
  reproductionFailureOutput?: string;
  verificationSuccessOutput?: string;
  lintOutput?: string;
  hint?: string;
  references?: string[];
  fixPatch?: string;
  errorLogs: string[];
  history: HistoryEntry[];
  totalCost: number;
}

HistoryEntry

interface HistoryEntry {
  step: Step;
  action: string;
  result: string;
  timestamp: number;
}

LLMMessage

interface LLMMessage {
  role: "system" | "user" | "assistant";
  content: string;
}

LLMResponse

interface LLMResponse {
  content: string;
  toolCalls?: ToolCall[];
  cost: number;
  usage: {
    promptTokens: number;
    completionTokens: number;
    totalTokens: number;
  };
}

ToolCall

interface ToolCall {
  id: string;
  name: string;
  arguments: Record<string, unknown>;
}

Inference Providers

All providers implement LLMProvider interface in src/inference/provider.ts.

LLMProvider Interface

interface LLMProvider {
  complete(messages: LLMMessage[], tools?: Tool[]): Promise<LLMResponse>;
  streamComplete?(messages: LLMMessage[], tools?: Tool[]): AsyncGenerator<LLMResponse>;
}

Available Providers

Provider Class Models Notes
OpenAI OpenAIProvider gpt-4o, gpt-4o-mini, o1 Official API
Anthropic AnthropicProvider claude-3-5-sonnet-latest Official API
Gemini GeminiProvider gemini-1.5-pro, gemini-1.5-flash API + CLI fallback
Mimo MimoProvider mimo-v2.5-pro Gitlab OpenGateway

Common Features

  • Retry Logic: Exponential backoff (3 attempts default)
  • Cost Tracking: Returns cost in USD per response
  • Secret Redaction: safeLogError() redacts API keys in logs
  • Prompt Sanitization: User data wrapped via wrapUserData()

Sandbox Execution

Two execution modes in src/sandbox/:

Docker (Default)

// src/sandbox/docker.ts
interface SandboxExecutor {
  buildImage(repoPath: string): Promise<string>;  // returns imageTag
  runCommand(imageTag: string, cmd: string, repoPath: string): Promise<CommandResult>;
  cleanup(imageTag: string): Promise<void>;
}

Build Process:

  1. Nixpacks detects language → generates Dockerfile
  2. docker build creates image tagged repatch-sandbox:{hash}
  3. Image cached for subsequent runs

Resource Limits (configurable):

  • Memory: 4GB default
  • CPUs: 2 default
  • Network: disabled default
  • Timeout: 300s default

Local (--local flag)

// src/sandbox/local.ts
interface LocalExecutor {
  setupLocalEnvironment(repoPath: string): Promise<LocalExecutionContext>;
  runLocalCommand(context: LocalExecutionContext, cmd: string): Promise<CommandResult>;
  getLocalTestCommand(context: LocalExecutionContext): string;
  getLocalLintCommand(context: LocalExecutionContext): string;
}

Language Detection (Nixpacks + fallback):

Language Detection File Install Command
Node.js package.json npm install
Python requirements.txt / pyproject.toml pip install -r requirements.txt
Go go.mod go mod download
Rust Cargo.toml cargo build
Java pom.xml / build.gradle mvn install / gradle build
Ruby Gemfile bundle install
PHP composer.json composer install

Configuration

Config Schema (src/config.ts)

const ConfigSchema = z.object({
  model: z.string().default("gpt-4o"),
  openai: z.object({
    apiKey: z.string().optional(),
    baseUrl: z.string().url().optional()
  }).optional(),
  anthropic: z.object({
    apiKey: z.string().optional()
  }).optional(),
  gemini: z.object({
    apiKey: z.string().optional()
  }).optional(),
  mimo: z.object({
    apiKey: z.string().optional(),
    baseUrl: z.string().url().optional()
  }).optional(),
  github: z.object({
    token: z.string().optional()
  }).optional(),
  sandbox: z.object({
    memory: z.string().default("4g"),
    cpus: z.number().default(2),
    network: z.boolean().default(false)
  }).optional()
});

Environment Variables

Variable Config Equivalent Required
OPENAI_API_KEY openai.apiKey One of
ANTHROPIC_API_KEY anthropic.apiKey One of
GEMINI_API_KEY gemini.apiKey One of
MIMO_API_KEY mimo.apiKey One of
GH_TOKEN github.token For PR submit
AI_MODEL model Optional

CLI Flags

Flag Description
-i, --issue <text> Issue description or GitHub issue URL
-h, --hint <text> Hint for the agent
--model <name> Override default model
--budget <usd> Max cost budget
--local Run without Docker
--resume Resume from checkpoint
--parallel <n> Parallel workers (fix-multi)
--max-retries <n> Max retries per issue
--good-first Filter good first issues (triage)
--json JSON output

Extending the System

Adding a Custom Tool

  1. Add to src/tools/registry.ts:
{
  name: "my_tool",
  description: "What it does",
  parameters: { /* Zod schema */ },
  handler: async (args) => { /* implementation */ }
}
  1. Declare availability in steps via availableInSteps (if using step-gating)

Adding a Custom Step

  1. Create src/orchestrator/steps/my-step.ts:
export class MyStep implements BaseStep {
  readonly name = "MY_STEP" as Step;
  constructor(private deps: StepDependencies) {}
  async execute(state: AgentState): Promise<StepResult> { ... }
}
  1. Register in src/orchestrator/machine.ts step order.

Adding a Custom LLM Provider

  1. Create src/inference/my-provider.ts implementing LLMProvider.
  2. Register in src/inference/provider.ts factory function createProvider().

Error Codes

Code Context Meaning
SANDBOX_BUILD_FAILED Docker build Nixpacks/Dockerfile issue
SANDBOX_TIMEOUT Command execution Command exceeded timeout
TOOL_VALIDATION_ERROR Tool call Args don't match schema
LLM_RATE_LIMIT Provider call 429 from API
LLM_TOKEN_LIMIT Provider call Context too large
GITHUB_AUTH_FAILED PR submit Invalid/missing GH_TOKEN
FUZZY_MATCH_FAILED Edit step Could not locate snippet
CHECKPOINT_CORRUPT Resume Invalid checkpoint file

Version Compatibility

Repatch Version Node.js TypeScript Docker
0.1.x 20+ 5.x 24+