Skip to content

Amp: register the provider instead of writing customAcpAgents (bb deprecates it in 0.40) #64

Description

@SawyerHood

What changes

bb is making every provider plugin-owned. Two things the Amp plugin depends on are moving:

  1. customAcpAgents in ~/.bb/config.json is deprecated. bb still reads it and registers what it finds, with a deprecation warning per agent, until 0.40. After that bb does not read it at all. plugins/amp/lib/provision.ts writes that array (provisionInstallationmanagedAgentEntry), so on 0.40 an installed Amp plugin would provision an entry nothing reads and acp-amp would vanish from the picker.
  2. The dynamic ACP tier is gone. An acp-* id that no plugin registered used to borrow capabilities and a bridge artifact from whichever ACP provider was registered first. Now an unregistered id is simply unknown: no capabilities, no bridge, not listed.

The replacement is the ordinary plugin API — the same one Amp already uses for its RPC, CLI, and app surfaces.

The recipe

Register the provider from server.ts instead of writing the config file. provision.ts keeps everything it does about resolving the Node runtime, the bridge bundle and the Amp CLI; only the "write it into config.json" step goes away, and its output becomes the registration's bridge options.

// server.ts
const launch = resolveBridgeLaunch(paths); // your existing provisioning
bb.providers.register({
  id: "acp-amp",                 // unchanged — threads persist provider ids
  displayName: "Amp",
  experimental_family: "acp",    // groups the ACP agents without parsing the id prefix
  icon: "./assets/icon.svg",     // a plugin-relative asset, no more logos/amp.svg in the data dir
  experimental_bridgeOptions: {
    acpLaunchSpec: {
      displayName: "Amp",
      command: launch.node,
      args: [launch.bridge],
      env: { AMP_CLI_PATH: launch.amp, ...(launch.electron ? { ELECTRON_RUN_AS_NODE: "1" } : {}) },
    },
  },
  experimental_nativeSkillRoots: AMP_NATIVE_SKILL_ROOTS, // now a declared capability
  capabilities: { /* … see below … */ },
  composerActions: [],
});

Notes on the pieces:

  • experimental_bridgeOptions is the opaque bag that reaches your bridge as options.providerOptions on every command — the same path bb's own ACP agents use. Your bridge already reads providerOptions.acpLaunchSpec, so nothing changes on the bridge side.
  • experimental_nativeSkillRoots: { user, project } replaces the nativeSkillRoots field you put in the config entry. It is a declared capability now, validated at registration (relative paths, no dot segments).
  • logo is gone. A plugin-registered provider's icon is a host glyph or a plugin-relative asset served from the registration, so ./assets/icon.svg replaces the logos/amp.svg file provisioning wrote into the data dir.
  • Registration is dynamic. bb.providers.register returns { dispose() }, and re-registering the same id after dispose() is explicitly allowed — so a settings change can re-register without a reload, which is what bb's own ACP plugin does.

Capabilities are per agent now, not per tier. The old tier declared one answer for every acp-* id, including fork: "tip". Declare what Amp actually does. If you want the exact answer rather than a guess, bb publishes a probe:

import { experimental_probeAcpAgent } from "@get-bb/plugin-sdk/provider-bridge/acp";
// in your bb.host entry: spawn, initialize, read agentCapabilities, kill.
// Never widens a declaration — only narrows one the agent denies.

You can keep your own bridge. Amp ships an ACP bridge built on @ampcode/sdk, and none of this asks you to replace it. If you ever want bb's generic one, it is published as @get-bb/plugin-sdk/provider-bridge/acp:

// host.ts (your `bb.host` entry)
export { experimental_acpProviderBridge as experimental_providerBridge }
  from "@get-bb/plugin-sdk/provider-bridge/acp";

The kit also publishes dialects — a per-agent module that reads an agent's vendor side channels (_meta, vendor JSON-RPC requests) without touching the shared ACP wire schema. If Amp puts anything beside the protocol (a tool name in _meta, a sub-agent report on its own request), experimental_registerAcpDialect is where that goes, and you name its id in experimental_bridgeOptions.acpDialect.

Migration for existing installs

An existing ~/.bb/config.json entry keeps working until 0.40, so a released plugin that registers properly and stops writing the array is safe on both sides: bb prefers a plugin registration over a legacy entry with the same id. Removing the entry your provisioning already wrote is optional and can be a one-time cleanup.

Where this is landing

The nine-PR stack in get-bb/bb: the ACP kit is published, the first-party ACP plugin registers its agents (bb's own list and the user's) from its own settings, and the tier is deleted. The kit's public surface is @get-bb/plugin-sdk/provider-bridge/acp; the audit notes are in docs/api_to_audit.md.

Happy to review a PR against this, or to answer anything the kit does not cover yet.

AGENT GENERATED: by Claude Opus 5

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions