Skip to content

feat: add Amp (Sourcegraph) as first-class agent with SDK + CLI support - #291

Merged
rubenmarcus merged 6 commits into
mainfrom
feat/amp-sdk-integration
Mar 12, 2026
Merged

feat: add Amp (Sourcegraph) as first-class agent with SDK + CLI support#291
rubenmarcus merged 6 commits into
mainfrom
feat/amp-sdk-integration

Conversation

@rubenmarcus

Copy link
Copy Markdown
Owner

Summary

Adds Amp by Sourcegraph as a first-class agent in ralph-starter, using the native @sourcegraph/amp-sdk for TypeScript integration with a CLI fallback.

Changes

Agent Abstraction (#235)

  • Added amp to AgentType union and AGENTS config object
  • Amp detection via amp --version
  • Ranked 2nd in preference order (after Claude Code, before Cursor)

Executor / Tool-use (#236)

  • runAmpAgent() — uses @sourcegraph/amp-sdk execute() async generator with structured message streaming, AbortSignal timeout, and error handling
  • runAmpCli() — CLI fallback using amp --execute --stream-json --dangerously-allow-all for environments without the SDK installed
  • Output format matches existing onOutput callback contract for step detection

Config + CLI Flags (#238)

  • --agent amp flag across run, auto, fix, figma, and template commands
  • --amp-mode <smart|rush|deep> flag for agent mode selection
  • AmpMode type exported from package index for SDK consumers
  • Wired through RunCommandOptionsLoopOptionsAgentRunOptions

Tests

  • Updated agent count from 5 → 6
  • Added test for amp fallback preference
  • Added test for amp > cursor preference ordering
  • All 254 tests pass ✅

Usage

# Basic
ralph-starter run --agent amp "implement the auth module"

# With mode selection
ralph-starter run --agent amp --amp-mode deep "refactor the database layer"

# In swarm mode
ralph-starter run --agent amp --swarm --strategy race "fix all lint errors"

Auth

Amp SDK uses AMP_API_KEY env var (access token from ampcode.com/settings). No browser-based OAuth needed for programmatic use.

Closes #234, #235, #236, #238

- Add 'amp' to AgentType union and AGENTS config (#235)
- Implement runAmpAgent() using @sourcegraph/amp-sdk execute() async generator
- Add CLI fallback via amp --execute --stream-json for environments without SDK
- Add --amp-mode flag (smart/rush/deep) for agent mode selection (#238)
- Wire ampMode through CLI → RunCommandOptions → LoopOptions → AgentRunOptions (#236)
- Export AmpMode type from package index for SDK consumers
- Amp ranked 2nd in agent preference (after Claude Code)
- Update tests for 6-agent detection and amp preference order

Closes #234, #235, #236, #238

Amp-Thread-ID: https://ampcode.com/threads/T-019ce298-ab61-760e-b725-803364016be5
Co-authored-by: Amp <amp@ampcode.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

github-actions Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

✔️ Bundle Size Analysis

Metric Value
Base 2576.91 KB
PR 2590.27 KB
Diff 13.35 KB (0%)
Bundle breakdown
156K	dist/auth
80K	dist/automation
4.0K	dist/cli.d.ts
4.0K	dist/cli.d.ts.map
20K	dist/cli.js
12K	dist/cli.js.map
584K	dist/commands
28K	dist/config
4.0K	dist/index.d.ts
4.0K	dist/index.d.ts.map
4.0K	dist/index.js
4.0K	dist/index.js.map
896K	dist/integrations
100K	dist/llm
1.1M	dist/loop
188K	dist/mcp
60K	dist/presets
92K	dist/setup
40K	dist/skills
392K	dist/sources
76K	dist/ui
144K	dist/utils
336K	dist/wizard

@greptile-apps

greptile-apps Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR integrates Amp by Sourcegraph as a first-class agent in ralph-starter, adding an SDK-first execution path (runAmpAgent using @sourcegraph/amp-sdk) with a CLI subprocess fallback (runAmpCli), preference-ranked second after Claude Code, and a new --amp-mode CLI flag for controlling reasoning depth. The dependency is correctly placed in optionalDependencies so existing users are not forced to download the SDK.

Key issues found:

  • --amp-mode silently dropped for auto command: The flag is registered on the auto subcommand but options.ampMode is never passed into the autoCommand(...) call — users specifying the mode get no error but no effect.
  • fix and figma commands omit --amp-mode: The PR description claims the flag is wired across five commands, but the diff only covers run, auto, and template. Both fix and figma are missing the option registration and forwarding.
  • runAmpCli output/byte counter desync after truncation: outputBytes is incremented by data.byteLength before the new chunk is appended to output. If truncation fires, outputBytes is recalculated from the trimmed buffer (without the incoming chunk), then output += chunk grows the buffer without a matching counter update — causing a persistent undercount after every truncation event.

Confidence Score: 3/5

  • Not safe to merge as-is — two user-visible flags silently do nothing and a memory-accounting bug exists in the CLI fallback path.
  • The core SDK integration and executor wiring are solid, but the CLI layer has two definitive gaps: --amp-mode is dropped by the auto command handler and is never added to fix/figma at all, directly contradicting the PR description. The runAmpCli byte-counter desync is a real logic bug, though limited in blast radius to post-truncation iterations.
  • src/cli.ts requires the most attention: the auto action handler is missing ampMode forwarding, and the fix/figma commands are missing the option entirely.

Important Files Changed

Filename Overview
src/loop/agents.ts Core of the PR — adds runAmpAgent (SDK path) and runAmpCli (subprocess fallback). SDK path is largely correct, but runAmpCli has an outputBytes/output desync after truncation. Preference order and type exports look correct.
src/cli.ts Registers --amp-mode on run, auto, and template commands, but omits it from fix and figma. Additionally, the auto action handler does not forward options.ampMode to autoCommand, silently dropping the flag.
src/loop/executor.ts Correctly threads ampMode from LoopOptions through AgentRunOptions. No issues found.
src/commands/run.ts Adds ampMode to RunCommandOptions and correctly passes it into LoopOptions. Install hint formatting is clean.
src/loop/tests/agents.test.ts Tests updated for 6-agent count, amp fallback preference, and amp > cursor ordering. Mock ordering matches the detection call order.
src/index.ts Correctly exports AmpMode type alongside Agent and AgentType. No issues.
package.json @sourcegraph/amp-sdk placed in optionalDependencies, which correctly avoids forcing installation on all users.
pnpm-lock.yaml Lockfile reflects optional SDK and its transitive deps (@sourcegraph/amp, @napi-rs/keyring). All platform binaries are marked optional in the snapshot.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[runAgent - agent.type === 'amp'] --> B[runAmpAgent]
    B --> C{import '@sourcegraph/amp-sdk'}
    C -- success --> D[SDK Path\nampSdk.execute async generator]
    C -- ImportError --> E[CLI Fallback\nrunAmpCli]

    D --> F[for await message of execute]
    F --> G[onOutput / streamOutput callbacks]
    G --> H{outputBytes > maxOutputBytes?}
    H -- yes --> I[Trim output to 80%\nRecalculate outputBytes]
    H -- no --> J[Continue]
    I --> J
    J --> K{message.type === 'result'?}
    K -- error --> L[Return exitCode: 1]
    K -- success --> M[Return exitCode: 0]
    K -- no --> F

    E --> N[spawn amp --execute --stream-json]
    N --> O[stdout data handler]
    O --> P{outputBytes > maxOutputBytes?}
    P -- yes --> Q[Trim output / Reset counter\n⚠ chunk appended AFTER reset]
    P -- no --> R[output += chunk]
    Q --> R
    R --> S[Parse NDJSON lines → onOutput]
    N --> T[setTimeout SIGTERM at timeoutMs]
    T --> U[Return exitCode: 124]
    N --> V[close event → exitCode]
Loading

Comments Outside Diff (2)

  1. src/cli.ts, line 333-348 (link)

    --amp-mode registered but silently dropped for auto command

    --amp-mode is registered as a CLI option on the auto command (line 322–325), but the action handler never forwards options.ampMode to autoCommand. Any user running ralph-starter auto --amp-mode deep will see no error, but the mode will be silently ignored.

  2. src/cli.ts, line 144-183 (link)

    --amp-mode missing from fix and figma commands

    The PR description states that --amp-mode is wired through run, auto, fix, figma, and template commands. The diff only adds the option to run, auto, and template. Neither the fix command (line 144–158) nor the figma command (line 162–183) registers --amp-mode, and their action handlers don't forward it to the underlying command functions. A user running ralph-starter fix --agent amp has no way to control the mode.

    Both commands need --amp-mode added to their option chain, and the corresponding ampMode: options.ampMode wired into the fixCommand/figmaCommand call objects.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/cli.ts
Line: 333-348

Comment:
**`--amp-mode` registered but silently dropped for `auto` command**

`--amp-mode` is registered as a CLI option on the `auto` command (line 322–325), but the action handler never forwards `options.ampMode` to `autoCommand`. Any user running `ralph-starter auto --amp-mode deep` will see no error, but the mode will be silently ignored.

```suggestion
  await autoCommand({
    source: options.source,
    project: options.project,
    label: options.label,
    limit: parseInt(options.limit, 10),
    dryRun: options.dryRun,
    skipPr: options.skipPr,
    agent: options.agent,
    ampMode: options.ampMode,
    validate: options.validate,
    maxIterations: options.maxIterations ? parseInt(options.maxIterations, 10) : undefined,
    batch: options.batch,
    model: options.model,
    parallel: options.parallel,
    concurrency: options.concurrency ? parseInt(options.concurrency, 10) : undefined,
  });
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/loop/agents.ts
Line: 451-462

Comment:
**`outputBytes` desyncs from `output` after truncation in `runAmpCli`**

`outputBytes` is incremented by `data.byteLength` **before** `chunk` is appended to `output`. When the limit is exceeded and truncation fires, `outputBytes` is recalculated from the trimmed `output` — but `chunk` hasn't been appended yet. After the `if` block, `output += chunk` grows `output` without a corresponding update to `outputBytes`, leaving the counter permanently underestimating the actual buffer size by `Buffer.byteLength(chunk)` after every truncation event.

Fix by appending `chunk` to `output` **before** the guard, mirroring the SDK path pattern:

```suggestion
    proc.stdout?.on('data', (data: Buffer) => {
      const chunk = data.toString();

      output += chunk;
      outputBytes += data.byteLength;
      stdoutBuffer += chunk;

      if (outputBytes > maxOutputBytes) {
        const keepBytes = Math.floor(maxOutputBytes * 0.8);
        output = output.slice(-keepBytes);
        outputBytes = Buffer.byteLength(output);
      }

      const lines = stdoutBuffer.split('\n');
      stdoutBuffer = lines.pop() || '';

      for (const line of lines) {
        if (line.trim()) {
          if (options.onOutput) options.onOutput(line);
          if (options.streamOutput) process.stdout.write(chalk.dim(`${line}\n`));
        }
      }
    });
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/cli.ts
Line: 144-183

Comment:
**`--amp-mode` missing from `fix` and `figma` commands**

The PR description states that `--amp-mode` is wired through `run`, `auto`, `fix`, `figma`, and `template` commands. The diff only adds the option to `run`, `auto`, and `template`. Neither the `fix` command (line 144–158) nor the `figma` command (line 162–183) registers `--amp-mode`, and their action handlers don't forward it to the underlying command functions. A user running `ralph-starter fix --agent amp` has no way to control the mode.

Both commands need `--amp-mode` added to their option chain, and the corresponding `ampMode: options.ampMode` wired into the `fixCommand`/`figmaCommand` call objects.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: bd0d259

Comment thread src/loop/agents.ts Outdated
Comment thread src/loop/agents.ts
- Fix dangerouslyAllowAll defaulting to true → false (security)
- Register --amp-mode flag on auto and template commands
- Add maxOutputBytes truncation guard to runAmpCli

Amp-Thread-ID: https://ampcode.com/threads/T-019ce298-ab61-760e-b725-803364016be5
Co-authored-by: Amp <amp@ampcode.com>
@rubenmarcus

Copy link
Copy Markdown
Owner Author

@greptileai

Comment thread src/loop/agents.ts
Comment thread pnpm-lock.yaml
Comment thread src/loop/agents.ts Outdated
- Add maxOutputBytes truncation guard to runAmpAgent SDK path
- Move @sourcegraph/amp-sdk to optionalDependencies to avoid bundling
  Amp CLI binary for all users and prevent false-positive agent detection
- Return exit code 124 on timeout (TimeoutError/AbortError) in SDK path,
  matching CLI path and runAgent behavior

Amp-Thread-ID: https://ampcode.com/threads/T-019ce298-ab61-760e-b725-803364016be5
Co-authored-by: Amp <amp@ampcode.com>
@rubenmarcus

Copy link
Copy Markdown
Owner Author

@greptileai

Comment thread src/loop/agents.ts Outdated
@rubenmarcus

Copy link
Copy Markdown
Owner Author

@greptileai

Comment thread src/loop/agents.ts
Comment thread src/commands/run.ts
- Pass options.env to SDK execute() (SDK supports env natively)
- Replace curl|bash install hint with npm install -g @sourcegraph/amp

Amp-Thread-ID: https://ampcode.com/threads/T-019ce298-ab61-760e-b725-803364016be5
Co-authored-by: Amp <amp@ampcode.com>
@rubenmarcus

Copy link
Copy Markdown
Owner Author

@greptileai

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: research Amp SDK API surface and map to agent abstraction

1 participant