Providers
bb.providers owns provider choice, the provider bridge protocol, and shared provider host control.
Purpose
The plugin gives each provider ID one replaceable implementation. It gives consumers one registry for models, health, usage, and maintenance.
The plugin also owns the typed server-to-host bridge. Provider plugins translate their native agent protocol into this common protocol.
The kernel still owns host transport and process isolation. bb.providers owns provider sessions, request control, recovery, and maintenance above those kernel ports.
Built-in provider plugins
The built-in provider plugins use the same contracts as all other provider plugins.
| Plugin ID | Provider implementation |
|---|---|
bb.claude-code |
Claude Code |
bb.codex |
Codex |
bb.pi |
Pi |
bb.acp |
The ACP family: Cursor, Pi ACP, and do.computer |
Each plugin claims bb.providers.provider, keyed by provider ID. Each plugin supplies its own keyed bb.providers.bridge host-role implementation and bridge artifacts.
These plugins have no special privilege. A marketplace provider claims the same contract and uses the same winner rules.
A fork claims the same keys and enters the normal winner selection. A provider plugin fork follows the same rules as any other plugin fork.
Surfaces
| ID | kind | replaceable | props contract sketch | notes |
|---|---|---|---|---|
| None | — | — | — | This plugin declares no app surface. Threads owns provider controls in the composer. Settings owns provider maintenance pages. |
Services
| ID | kind | replaceable | contract | notes |
|---|---|---|---|---|
bb.providers |
single |
yes | ProvidersService |
The first-party implementation is the default provider. |
bb.providers.provider |
keyed by provider ID |
yes | Provider |
The current claimant supplies one provider ID. Each key has its own winner and fallback. |
bb.providers
This service is the registry and control plane. Read methods use the current winner for each provider key.
| Method | Result | Notes |
|---|---|---|
list(query?) |
ProviderRecord[] |
Lists visible provider keys and winner state. |
get(providerId) |
ProviderRecord | null |
Reads one provider key without a host call. |
resolve(providerId) |
Provider |
Returns the live keyed provider handle. |
watch(listener) |
Unsubscribe |
Reports add, change, winner, health, and removal events. |
models(providerId, context) |
ModelCatalog |
Uses the host cache and the declaration fallback list. |
health(providerId, context) |
ProviderHealth |
Runs a sessionless health request. |
usage(providerId, context) |
ProviderUsage |
Reads provider account limits. |
installationStatus(providerId, context) |
ProviderInstallationStatus |
Reads the CLI state and available action. |
runInstallation(providerId, context, action) |
ProviderInstallationRunResult |
Runs one declared install or update action. |
export interface ProvidersService {
list(query?: ProviderListQuery): Promise<readonly ProviderRecord[]>;
get(providerId: string): Promise<ProviderRecord | null>;
resolve(providerId: string): Promise<Provider>;
watch(listener: (event: ProviderRegistryEvent) => void): Unsubscribe;
models(providerId: string, context: ProviderHostContext): Promise<ModelCatalog>;
health(providerId: string, context: ProviderHostContext): Promise<ProviderHealth>;
usage(providerId: string, context: ProviderHostContext): Promise<ProviderUsage>;
installationStatus(
providerId: string,
context: ProviderHostContext,
): Promise<ProviderInstallationStatus>;
runInstallation(
providerId: string,
context: ProviderHostContext,
action: "install" | "update",
): Promise<ProviderInstallationRunResult>;
}
export interface ProviderRecord {
providerId: string;
declaration: ProviderDeclaration;
winner: { pluginId: string; generation: number; isDefault: boolean };
claimants: readonly { pluginId: string; version: string; state: ProviderClaimState }[];
availability: "ready" | "unavailable" | "degraded" | "failed";
lastFailure?: ProviderFailure;
}
export type ProviderRegistryEvent =
| { kind: "added" | "changed"; record: ProviderRecord }
| { kind: "winner-changed"; providerId: string; previousPluginId: string; record: ProviderRecord }
| { kind: "removed"; providerId: string }
| { kind: "health-changed"; providerId: string; health: ProviderHealth };A keyed winner change uses the backend replacement transaction. The candidate must become ready before cutover.
The runtime drains old calls to a deadline. It then restarts required dependents in graph order.
The first claim for a new key must declare itself as that key's default. A later replacement claim cannot change this fallback.
bb.providers.provider
Each claim implements one provider ID. The declaration is static, but the methods can use settings and host state.
| Method | Result | Notes |
|---|---|---|
declaration() |
ProviderDeclaration |
Returns the claim data from contract.json. |
deriveOptions(context) |
JsonObject |
Derives per-command bridge options. |
models(context) |
ModelCatalog |
Returns a live catalog or the fallback catalog. |
health(context) |
ProviderHealth |
Uses the bridge only when the declaration enables health. |
usage(context) |
ProviderUsage |
Uses the bridge only when the declaration enables usage. |
installationStatus(context) |
ProviderInstallationStatus |
Uses shared maintenance probes. |
runInstallation(context, action) |
ProviderInstallationRunResult |
Uses a declared command and verification rule. |
resolveNativeRoots(context) |
ProviderResolvedNativeRoots |
Resolves host-specific skill and command roots. |
openSession(context) |
ProviderSession |
Opens one supervised bridge session. |
export interface Provider {
declaration(): ProviderDeclaration;
deriveOptions(context: ProviderOptionsContext): Promise<JsonObject>;
models(context: ProviderHostContext): Promise<ModelCatalog>;
health(context: ProviderHostContext): Promise<ProviderHealth>;
usage(context: ProviderHostContext): Promise<ProviderUsage>;
installationStatus(context: ProviderHostContext): Promise<ProviderInstallationStatus>;
runInstallation(
context: ProviderHostContext,
action: "install" | "update",
): Promise<ProviderInstallationRunResult>;
resolveNativeRoots(context: NativeRootsContext): Promise<ProviderResolvedNativeRoots>;
openSession(context: ProviderSessionContext): Promise<ProviderSession>;
}
export interface ProviderSession {
start(input: ThreadStartRequest): Promise<ThreadIdentityResult>;
resume(input: ThreadResumeRequest): Promise<ThreadIdentityResult>;
fork(input: ThreadForkRequest): Promise<ThreadIdentityResult>;
stop(input: ThreadStopRequest): Promise<void>;
discard(input: ThreadIdentityRequest): Promise<void>;
archive(input: ThreadIdentityRequest): Promise<void>;
unarchive(input: ThreadIdentityRequest): Promise<void>;
setName(input: ThreadNameSetRequest): Promise<void>;
clearGoal(input: ThreadIdentityRequest): Promise<void>;
startTurn(input: TurnStartRequest): Promise<void>;
steerTurn(input: TurnSteerRequest): Promise<void>;
configureSkills(input: SkillsConfigureRequest): Promise<void>;
close(): Promise<void>;
}Provider declaration
The contract uses the liked 1.0 declaration shape. It makes static choices reviewable before code starts.
export interface ProviderDeclaration {
id: string;
displayName: string;
family?: string;
icon?: string;
visibility: "always" | "installed";
capabilities: ProviderCapabilities;
composerActions: readonly ("plan" | "goal")[];
strings?: ProviderStrings;
serviceTiers?: readonly ProviderOption[];
reasoningLevels?: readonly ProviderOption[];
maintenance?: ProviderMaintenance;
extensionKinds?: Readonly<Record<string, ProviderExtensionKind>>;
models?: {
fallback?: readonly ProviderFallbackModel[];
scope?: "host" | "workspace";
};
env?: { passthrough: readonly string[] };
bridgeOptions?: JsonObject;
nativeRoots?: {
skills?: readonly ProviderNativeRoot[];
commands?: readonly ProviderNativeRoot[];
resolveOnHost?: boolean;
};
}
export interface ProviderCapabilities {
supportsServiceTier: boolean;
supportsNativeUserQuestion: boolean;
fork: "none" | "thread" | "checkpoint";
supportsManualCompaction: boolean;
supportsThreadArchive: boolean;
supportsThreadRename: boolean;
permissionModes: readonly ("accept-edits" | "auto" | "full")[];
reasoningLevels: readonly string[];
}
export interface ProviderStrings {
signInHint: string;
expiredHint: string;
installUrl: string;
brandPrefix?: string;
planModeCopy?: string;
iconTint?: { light: string; dark: string };
}
export interface ProviderOptionsContext {
threadId: string;
projectId: string;
model: string;
permissionMode: "accept-edits" | "auto" | "full";
promptMode?: "plan";
settings: Readonly<Record<string, string | boolean | undefined>>;
}
export interface ProviderFallbackModel {
id: string;
displayName: string;
description: string;
supportedReasoningEfforts: readonly {
reasoningEffort: string;
description: string;
}[];
defaultReasoningEffort: string;
isDefault: boolean;
}
export interface ProviderOption {
id: string;
label: string;
description?: string;
}
export interface ProviderExtensionKind {
item?: StandardSchemaV1;
state?: StandardSchemaV1;
}
export interface ProviderNativeRoot {
id: string;
path: string;
}The build checks each extension item and state schema. The runtime rejects an undeclared extension kind.
Bridge protocol
bb.providers.bridge uses newline-delimited JSON-RPC 2.0. The handshake selects a thread-delta grammar in the supported range.
The public module is @bb/providers/bridge. It contains schemas, types, a bridge factory, and a conformance kit.
Transport and entry
export interface ProviderBridgeEntry {
apiVersion: 1;
definition: ProviderBridgeDefinition;
}
export interface ProviderBridgeDefinition {
start?(context: ProviderBridgeContext): void | Promise<void>;
handleLine(line: string): void;
onClose?(): void | Promise<void>;
onSigterm?(): void | Promise<void>;
onSigint?(): void | Promise<void>;
}
export interface ProviderBridgeContext {
pluginId: string;
providerId: string;
dataDir: string;
tempDir: string;
signal: AbortSignal;
}
export function defineProviderBridge(
definition: ProviderBridgeDefinition,
): ProviderBridgeEntry;One line has a 64 MiB limit. An overflow closes the bridge with a protocol error.
Handshake
| Method | Direction | Input | Output |
|---|---|---|---|
initialize |
runtime to bridge | protocol version, client data, grammar range | protocol version and BridgeCapabilities |
export interface BridgeCapabilities {
sessionRestore: boolean;
threadArchive: boolean;
threadRename: boolean;
threadGoalClear: boolean;
fork: "none" | "thread" | "checkpoint";
approvalEnforcedBy: "runtime" | "provider";
grammarVersions: readonly [minimum: number, maximum: number];
steerMode: "inject" | "queue";
skills: { configure: boolean };
}The runtime chooses the highest common grammar. A bridge cannot report a capability wider than its static declaration.
Runtime requests
| Method | Input | Output | Gate |
|---|---|---|---|
model/list |
{ cwd? } |
available and selected-only models | live catalog |
provider/health |
host context and options | ProviderHealth |
maintenance.health |
provider/usage |
provider ID, host context, options | ProviderUsage |
maintenance.usage |
provider/installation/status |
provider ID, host context, requirement | ProviderInstallationStatus |
maintenance.installation |
provider/installation/run |
provider ID, host context, action | ProviderInstallationRunResult |
maintenance.installation |
thread/start |
thread, workspace, tools, options, initial input | ThreadIdentityResult |
always |
thread/resume |
thread and provider thread identity | ThreadIdentityResult |
sessionRestore |
thread/fork |
source identity and optional checkpoint | ThreadIdentityResult |
fork |
thread/stop |
intent and active turn | {} |
always |
thread/discard |
thread identity | {} |
always |
thread/name/set |
thread identity and title | {} |
threadRename |
thread/archive |
thread identity | {} |
threadArchive |
thread/unarchive |
thread identity | {} |
threadArchive |
thread/goal/clear |
thread identity | {} |
threadGoalClear |
turn/start |
input, client request ID, options | {} |
always |
turn/steer |
expected turn, input, request ID, options | {} |
steerMode |
skills/configure |
normalized roots and skill descriptions | {} |
skills.configure |
export interface BridgeExecutionOptions {
model?: string;
serviceTier?: string;
reasoningLevel?: string;
promptMode?: "plan";
instructions?: string;
envVars?: Readonly<Record<string, string>>;
providerOptions?: JsonObject;
}Bridge requests and notifications
The bridge can request one tool call or one user interaction. The shared request service tracks both request types.
| Method | Direction | Contract |
|---|---|---|
item/tool/call |
bridge to runtime | Tool name, call ID, arguments, and thread identity. |
interaction/request |
bridge to runtime | A typed approval, question, secret, or open interaction. |
thread/identity |
bridge notification | Maps a bb thread to a provider thread. |
session/replaced |
bridge notification | Reports a new session and possible context loss. |
provider/raw |
bridge notification | Preserves unknown or noise data. |
provider/recovery |
bridge notification | Gives typed recovery advice. |
error |
bridge notification | Reports an unscoped bridge error. |
thread/delta |
bridge notification | Sends ordered normalized deltas. |
export type PendingInteractionPayload =
| ApprovalInteraction
| QuestionInteraction
| SecretInteraction
| OpenInteraction;
export interface SecretInteraction {
kind: "secret";
requestKey: string;
title: string;
prompt: string;
secretName: string;
}
export type PendingInteractionResolution =
| { kind: "approval"; decision: "allow_once" | "allow_for_session" | "deny" }
| { kind: "answer"; answers: readonly string[] }
| { kind: "secret"; stored: boolean }
| { kind: "submitted"; data: JsonValue }
| { kind: "interrupted"; reason: string };The secret value never enters a delta or a server log. The kernel secrets port stores it.
Thread deltas
A thread/delta notification contains one ordered ThreadDelta[]. Each item event uses a stable DeltaItemKey.
export interface DeltaItemKey {
providerItemId?: string;
channel?: string;
parentRef?: string;
}
export type DeltaItem =
| CommandItem | FileChangeItem | ToolItem | CompactionItem
| AgentMessageItem | ReasoningItem | PlanItem
| WebSearchItem | WebFetchItem | ImageViewItem
| BackgroundTaskItem | FileReadItem | SearchItem
| DelegationItem | PlanStepsItem | ExtensionItem;
export type ThreadDelta =
| InputAcceptedDelta | InputProviderDelta
| TurnOpenDelta | TurnBoundaryDelta | TurnDiffDelta
| ItemOpenDelta | ItemCloseDelta | ItemProgressDelta
| TextDelta | TextCloseDelta | OutputDelta | CommandOutputSnapshotDelta
| UsageDelta | ContextWindowDelta | ContextCompactedDelta | ContextClearedDelta
| ThreadStartedDelta | ThreadIdentityDelta | ThreadNameDelta
| ExtensionStateDelta | ProviderRateLimitsDelta | ProviderErrorDelta
| ProviderModelFallbackDelta | ProviderWarningDelta | UnhandledDelta
| SessionEndedDelta | SessionResetDelta;| Delta kind | Required data | Effect |
|---|---|---|
input.accepted |
client request and optional provider turn | Confirms accepted input. |
input.provider |
text and optional parent | Adds provider-side input. |
turn.open |
provider turn and parent | Opens a turn. |
turn.boundary |
status, error, checkpoint, turn | Settles or changes a turn. |
item.open |
key, full item, presentation | Opens an item. |
item.close |
key, status, full item, result | Settles an item. |
item.progress |
key, message or snapshot | Updates progress. |
item.textDelta |
key, text channel, text | Adds streamed text. |
item.textClose |
key, text channel, optional final text | Closes streamed text. |
item.outputDelta |
key, output channel, text | Adds command or file output. |
command.outputSnapshot |
key and full output | Replaces command output. |
usage |
last and total usage | Updates token usage. |
contextWindow |
used size and estimate flag | Updates context use. |
context.compacted |
turn reference | Reports compaction. |
context.cleared |
kind only | Reports cleared context. |
turn.diff |
diff and turn reference | Adds a turn diff. |
thread.started |
kind only | Reports provider thread start. |
thread.identity |
provider thread ID | Updates identity. |
thread.name |
name | Updates the provider name. |
extension.state |
extension kind and payload | Updates extension state. |
provider.rateLimits |
normalized rate-limit state | Updates limits. |
provider.error |
message, category, retry data | Reports a provider failure. |
provider.modelFallback |
model pair, reason, message | Reports model fallback. |
provider.warning |
summary, details, category | Reports a warning. |
unhandled |
raw event and coverage data | Preserves unmapped data. |
session.ended |
kind only | Ends the session. |
session.reset |
kind only | Resets the session state. |
Item close events repeat the full item. This rule makes event replay independent from bridge memory.
The grammar accepts text channels agentMessage, reasoningSummary, reasoningText, and plan. It accepts output channels command and fileChange.
Unknown events use ProviderRawEvent. A coverage value of noise permits a drop after diagnostics.
Item contracts
All item variants have a type field. An extension item also has a declared schema.
| Item type | Main data |
|---|---|
command |
Command, work directory, output, exit code, status, and approval state. |
fileChange |
Path, add or update or delete kind, move path, diff, old text, and new text. |
tool |
Tool name, call ID, arguments, result, status, and presentation. |
compaction |
Cause, status, and optional summary. |
agentMessage |
Assistant text and status. |
reasoning |
Summary text, detail text, and status. |
plan |
Plan text and status. |
webSearch |
Query, sources, and status. |
webFetch |
URL, title, result, and status. |
imageView |
Path or URL, detail, and status. |
backgroundTask |
Family, task type, description, status, usage, output file, summary, and error. |
fileRead |
Path and optional command. |
search |
Mode, query, path, and optional command. |
delegation |
Child reference, label, background flag, and summary. |
planSteps |
Ordered steps and optional explanation. |
extension |
Declared extension kind and validated JSON payload. |
export interface DeltaFileChange {
path: string;
kind: "add" | "update" | "delete";
movePath?: string;
diff?: string;
oldText?: string;
newText?: string;
}
export interface BackgroundTaskItem {
type: "backgroundTask";
familyId: string;
taskType: string;
description: string;
status: string;
taskStatus: string;
skipTranscript: boolean;
workflowName?: string;
workflow?: JsonValue;
usage?: ProviderTokenUsage;
summary?: string;
error?: string;
outputFile?: string;
}
export interface DelegationItem {
type: "delegation";
childRef: string;
label: string;
background: boolean;
summary?: string;
}
export interface PlanStepsItem {
type: "planSteps";
steps: readonly ThreadPlanStep[];
explanation?: string;
}
export interface ExtensionItem {
type: "extension";
kind: string;
payload: JsonValue;
}Maintenance, health, and usage
export interface ProviderMaintenance {
health?: boolean;
usage?: boolean;
installation?: boolean;
}
export interface ProviderHealth {
status: "ok" | "not_installed" | "unauthenticated" | "expired" | "unsupported" | "error";
statusMessage?: string;
accountEmail?: string;
planLabel?: string;
installedVersion?: string;
minimumSupportedVersion?: string;
canInstall: boolean;
canUpdate: boolean;
loginCommand?: string;
}
export type ProviderUsage =
| { status: "ok"; accountEmail?: string; planLabel?: string; windows: readonly ProviderUsageWindow[] }
| { status: "not_installed" | "unauthenticated" | "expired" }
| { status: "error"; message: string; accountEmail?: string; planLabel?: string };
export interface ProviderUsageWindow {
label: string;
usedPercent: number;
resetsAt: string | null;
cost?: { usedUsdCents: number; limitUsdCents: number };
}
export interface ProviderInstallationStatus {
executableName: string;
executablePath: string | null;
installed: boolean;
installSource: "npm-global" | "path" | "download" | "unknown";
currentVersion: string | null;
latestVersion: string | null;
minimumSupportedVersion: string | null;
npmPackageName?: string;
npmGlobalPackageVersion?: string | null;
installAction?: ProviderInstallationAction;
needsUpdate: boolean;
versionUnsupported: boolean;
}
export interface ProviderInstallationCommand {
command: string;
args: readonly string[];
displayCommand: string;
}
export interface ProviderInstallationAction {
kind: "install" | "update";
label: "Install" | "Update";
command: ProviderInstallationCommand;
}
export type ProviderInstallationVerification =
| { kind: "installed" }
| { kind: "version_changed"; previousVersion: string | null }
| { kind: "version_at_least"; version: string };
export type ProviderInstallationRunResult =
| { available: false; message: string }
| {
available: true;
command: ProviderInstallationCommand;
verification: ProviderInstallationVerification;
};An install run returns the exact command and a verification rule. Shared maintenance code verifies the result after execution.
Recovery and errors
export type ProviderRecoveryKind =
| "restart-process"
| "resume-fresh"
| "reauthenticate"
| "reinstall"
| "none";
export interface ProviderRecoveryHint {
kind: ProviderRecoveryKind;
message: string;
retryable: boolean;
}
export const BRIDGE_JSON_RPC_ERRORS = {
INVALID_PARAMS: -32602,
METHOD_NOT_FOUND: -32601,
BRIDGE_ERROR: -32000,
NO_ACTIVE_TURN: -32001,
SESSION_NOT_RESTORABLE: -32002,
FORK_CHECKPOINT_UNSUPPORTED: -32003,
} as const;The supervisor rejects pending requests when a process exits. It records the recovery hint with the provider and session state.
Protocol runtime utilities
The bridge module provides a small runtime above the host services. Provider adapters do not write their own JSON-RPC loop.
| Area | Exact contract |
|---|---|
| JSON-RPC messages | JsonRpcMessage, ProviderInboundRequest, ProviderRuntimeEvent, and command plans. |
| JSON-RPC output | send, sendResult, sendError, and recovery-aware request dispatch. |
| Line input | A bounded line reader with overflow and close callbacks. |
| Tool calls | Request and response codecs, content blocks, image decode, and one pending-call tracker. |
| Interactions | A decoder and one pending-request tracker with process-scope rejection. |
| Raw events | Parse, describe, and classify each event as normalized, noise, or unknown. |
| Child environment | Remove bridge-only values before a provider process starts. |
| Record mode | Store bounded child input and output records through the supervisor. |
export interface ProviderRequestClient {
request<T>(method: string, params: JsonValue, options?: { signal?: AbortSignal }): Promise<T>;
notify(method: string, params: JsonValue): void;
handleResponse(response: BridgeJsonRpcResponse): boolean;
rejectAll(message: string): void;
}
export interface ProviderVisibilityMetadata<TRawEvent> {
parseRawEvent(input: unknown): TRawEvent | null;
describeParsedRawEvent(event: TRawEvent): ProviderRawEventDescription;
describeRawEvent(input: unknown): ProviderRawEventDescription;
}Exports
| Module | Exports |
|---|---|
@bb/providers/contracts |
bbProviders, bbProvider, all server interfaces, and provider declaration schemas. |
@bb/providers/app |
useProviders, ProviderIcon, ProviderDirectoryState |
@bb/providers/bridge |
Bridge entry factory, protocol schemas, deltas, items, interactions, maintenance types, and JSON-RPC helpers. |
@bb/providers/bridge/testing |
Memory transport, conformance runner, protocol fixtures, and transcript checks. |
@bb/providers/host |
Host role tokens, supervisor clients, request clients, maintenance helpers, and native-root helpers. |
@bb/providers/bridge/acp |
Experimental ACP probe, launch, bridge, and presentation helpers. |
Direct imports select exact code. Service and host-role tokens follow the current winner.
export interface ProviderDirectoryState {
status: "loading" | "ready" | "error";
providers: readonly ProviderRecord[];
}
export function useProviders(): ProviderDirectoryState;
export interface ProviderIconProps {
providerId: string;
className?: string;
}
export const ProviderIcon: ComponentType<ProviderIconProps>;The provider declaration supplies its icon data.
A plugin can export an exact React icon module when the declared asset cannot represent its mark.
The 2.0 API drops the global experimental_providerIcon registration slot.
Host roles
| ID | kind | replaceable | role contract | notes |
|---|---|---|---|---|
bb.providers.bridge |
keyed by provider ID |
yes | ProviderBridgeRole |
The public provider service depends on this private role. |
bb.providers.nativeRoots |
keyed by provider ID |
yes | ProviderNativeRootsRole |
The provider claim can omit this role when roots are static. |
export interface ProviderBridgeRole {
initialize(input: InitializeRequest): Promise<InitializeResult>;
request<M extends RuntimeBridgeMethod>(
method: M,
input: RuntimeBridgeInput<M>,
options?: { signal?: AbortSignal },
): Promise<RuntimeBridgeOutput<M>>;
toolResult(requestId: string | number, result: BridgeToolCallResult): Promise<void>;
interactionResult(
requestId: string | number,
result: PendingInteractionResolution,
): Promise<void>;
events(listener: (event: ProviderBridgeEvent) => void): Unsubscribe;
close(reason: string): Promise<void>;
}
export interface ProviderNativeRootsRole {
resolve(input: { providerId: string; cwd: string | null }): Promise<ProviderResolvedNativeRoots>;
}The manifest joins both claims by the same provider key. The inspector shows the server generation and host generation in one record.
Shared provider host services
Provider roles use these services. They do not implement process and request control again.
| ID | kind | replaceable | purpose |
|---|---|---|---|
bb.providers.host.supervisor |
single |
no | Owns provider processes, sessions, exit policy, leases, and transcript records. |
bb.providers.host.requests |
single |
no | Owns pending JSON-RPC requests, timeouts, tool calls, and interactions. |
bb.providers.host.maintenance |
single |
no | Owns executable probes, versions, install commands, and verification. |
bb.providers.host.declarations |
single |
no | Reconciles dynamic provider declarations and native roots. |
export interface ProviderHostSupervisor {
spawn(spec: ProviderLaunchSpec): Promise<ProviderProcess>;
attach(identity: ProviderProcessIdentity): Promise<ProviderProcess>;
getSession(scope: ProviderSessionScope): ProviderSupervisedSession | null;
closeSession(scope: ProviderSessionScope, reason: string): Promise<void>;
closeAll(providerId: string, reason: string): Promise<void>;
childEnv(input: NodeJS.ProcessEnv, session: Readonly<Record<string, string>>): NodeJS.ProcessEnv;
recordChildIo(scope: ProviderSessionScope, record: ProviderChildIoRecord): Promise<void>;
retainWorker(scope: ProviderSessionScope): ProviderWorkerLease;
}
export interface ProviderHostRequests {
createClient(process: ProviderProcess, options: ProviderRequestOptions): ProviderRequestClient;
decodeResponse(input: unknown): BridgeJsonRpcResponse | null;
decodeToolResult(input: unknown): DecodedBridgeToolResult;
buildToolContent(input: ToolResultInput): readonly BridgeToolCallContent[];
failScope(scope: ProviderSessionScope, message: string): void;
}
export interface ProviderHostMaintenance {
resolveExecutable(command: string): Promise<string | null>;
commandOutput(command: string, args: readonly string[]): Promise<string | null>;
versionFrom(value: string | null): string | null;
readCliVersion(command: string): Promise<string | null>;
compareVersions(left: string, right: string): number;
npmCommand(): string;
formatCommand(command: string, args: readonly string[]): string;
npmInstall(npmPackage: string): ProviderInstallationCommand;
npmLatest(npmPackage: string): Promise<string | null>;
npmProbe(npmPackage: string): Promise<NpmGlobalPackageProbe>;
installSource(input: InstallSourceInput): ProviderInstallationSource;
installationVerification(
status: Pick<ProviderInstallationStatus, "currentVersion" | "latestVersion">,
action: "install" | "update",
): ProviderInstallationVerification;
downloadedInstaller(url: string): ProviderInstallationCommand;
clampPercent(value: number): number;
}
export interface ProviderHostDeclarations {
apply(source: string, declarations: readonly ProviderDeclaration[]): Promise<DeclarationDiff>;
removeSource(source: string): Promise<void>;
snapshot(): readonly ProviderDeclaration[];
watch(listener: (diff: DeclarationDiff) => void): Unsubscribe;
filterNativeRoots(input: ProviderResolvedNativeRootsInput): FilteredNativeRoots;
}The supervisor gives every session one process identity. It applies timeouts, aborts, exit rejection, and kill escalation.
The declaration service applies one atomic diff. ACP does not need disposer maps or declaration polls in its server half.
Experimental host adapters
The host module exports experimental_resolveClaudePluginRoots and experimental_resolveVendorPluginRoots. Both return normalized native roots.
The ACP module exports these experimental helpers:
experimental_acpAgentProbeSchemaexperimental_acpLaunchSpecSchemaexperimental_acpProviderBridgeexperimental_probeAcpAgentexperimental_toolPresentation
These exports keep the experimental stability marker. They use the stable bridge and supervisor contracts underneath.
Example
This provider claims one server key and one host-role key. The user can choose another claimant for acme.
{
"id": "acme.provider",
"version": "2.0.0",
"claims": [
{ "service": "bb.providers.provider", "version": "^1", "key": "acme", "default": true },
{ "hostRole": "bb.providers.bridge", "version": "^1", "key": "acme", "default": true }
],
"requires": [{ "service": "bb.providers", "range": "^1" }],
"artifacts": {
"server": "./dist/server.js",
"host": "./dist/host.js"
}
}// server.ts
import { defineServerPlugin } from "@get-bb/plugin/server";
import { bbProvider } from "@bb/providers/contracts";
import { declaration } from "./declaration.js";
export default defineServerPlugin((api) => {
api.services.provide(bbProvider, {
declaration: () => declaration,
deriveOptions: async ({ settings }) => ({ apiBase: settings.apiBase ?? null }),
models: (context) => api.host.roles.call("bb.providers.bridge", "model/list", context),
health: (context) => api.host.roles.call("bb.providers.bridge", "provider/health", context),
usage: (context) => api.host.roles.call("bb.providers.bridge", "provider/usage", context),
installationStatus: (context) => api.host.roles.call("bb.providers.bridge", "provider/installation/status", context),
runInstallation: (context, action) => api.host.roles.call("bb.providers.bridge", "provider/installation/run", { ...context, action }),
resolveNativeRoots: (context) => api.host.roles.call("bb.providers.nativeRoots", "resolve", context),
openSession: (context) => api.host.roles.session("bb.providers.bridge", context),
}, { key: "acme" });
});// host.ts
import { defineHostPlugin } from "@get-bb/plugin/host";
import { bbProviderBridgeRole, bbProviderHostSupervisor } from "@bb/providers/host";
import { createAcmeBridge } from "./acme-bridge.js";
export default defineHostPlugin(async (api) => {
const supervisor = await api.services.use(bbProviderHostSupervisor);
api.hostRoles.provide(
bbProviderBridgeRole,
createAcmeBridge({ supervisor, declaration }),
{ key: "acme" },
);
});The runtime stages both halves before it changes the winner. A failed host candidate cannot remove the current acme provider.
Covers
| old item ID | new contract/verb | note |
|---|---|---|
server.providers |
bb.providers.provider contract | The keyed contract replaces the registration namespace. |
server.providers.register |
api.services.provide(bbProvider, implementation, { key }) | The factory scope supplies automatic cleanup. |
server.providers.declaration |
bb.providers.provider: ProviderDeclaration | The static declaration remains part of contract.json. |
server.providers.capabilities |
bb.providers.provider: ProviderCapabilities | |
server.providers.maintenance |
bb.providers.provider: ProviderMaintenance | |
server.providers.strings |
bb.providers.provider: ProviderStrings | |
server.providers.optionsContext |
bb.providers.provider: ProviderOptionsContext | |
server.providers.declaration.id |
bb.providers.provider: ProviderDeclaration.id | |
server.providers.declaration.displayName |
bb.providers.provider: ProviderDeclaration.displayName | |
server.providers.declaration.family |
bb.providers.provider: ProviderDeclaration.family | |
server.providers.declaration.icon |
bb.providers.provider: ProviderDeclaration.icon | |
server.providers.declaration.experimental_bridgeOptions |
bb.providers.provider: ProviderDeclaration.bridgeOptions | The stable declaration field replaces the experimental field. |
server.providers.declaration.experimental_visibility |
bb.providers.provider: ProviderDeclaration.visibility | The stable declaration field replaces the experimental field. |
server.providers.declaration.maintenance |
bb.providers.provider: ProviderDeclaration.maintenance | |
server.providers.declaration.capabilities |
bb.providers.provider: ProviderDeclaration.capabilities | |
server.providers.declaration.composerActions |
bb.providers.provider: ProviderDeclaration.composerActions | |
server.providers.declaration.strings |
bb.providers.provider: ProviderDeclaration.strings | |
server.providers.declaration.serviceTiers |
bb.providers.provider: ProviderDeclaration.serviceTiers | |
server.providers.declaration.reasoningLevels |
bb.providers.provider: ProviderDeclaration.reasoningLevels | |
server.providers.declaration.extensionKinds |
bb.providers.provider: ProviderDeclaration.extensionKinds | |
server.providers.declaration.models |
bb.providers.provider: ProviderDeclaration.models | |
server.providers.declaration.env |
bb.providers.provider: ProviderDeclaration.env | |
server.providers.declaration.experimental_nativeSkillRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.skills | The stable native-roots object replaces the experimental field. |
server.providers.declaration.experimental_nativeCommandRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.commands | The stable native-roots object replaces the experimental field. |
server.providers.declaration.experimental_resolvesNativeRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.resolveOnHost | The stable native-roots object replaces the experimental field. |
server.providers.declaration.deriveProviderOptions |
bb.providers.provider: Provider.deriveOptions() | Behavior moves from declaration data to the provider service. |
server.providers.capabilities.permissionModes |
bb.providers.provider: ProviderCapabilities.permissionModes | |
server.providers.capabilities.reasoningLevels |
bb.providers.provider: ProviderCapabilities.reasoningLevels | |
server.providers.maintenance.health |
bb.providers.provider: ProviderMaintenance.health | |
server.providers.maintenance.usage |
bb.providers.provider: ProviderMaintenance.usage | |
server.providers.maintenance.installation |
bb.providers.provider: ProviderMaintenance.installation | |
server.providers.optionDescriptor |
bb.providers.provider: ProviderOption | |
server.providers.extensionKind |
bb.providers.provider: ProviderExtensionKind | |
server.providers.fallbackModel |
bb.providers.provider: ProviderFallbackModel | |
server.providers.fallbackModel.supportedReasoningEfforts |
bb.providers.provider: ProviderFallbackModel.supportedReasoningEfforts | |
server.providers.fallbackModel.defaultReasoningEffort |
bb.providers.provider: ProviderFallbackModel.defaultReasoningEffort | |
server.providers.fallbackModel.isDefault |
bb.providers.provider: ProviderFallbackModel.isDefault | |
server.providers.capabilities.supportsServiceTier |
bb.providers.provider: ProviderCapabilities.supportsServiceTier | |
server.providers.capabilities.supportsNativeUserQuestion |
bb.providers.provider: ProviderCapabilities.supportsNativeUserQuestion | |
server.providers.capabilities.fork |
bb.providers.provider: ProviderCapabilities.fork | |
server.providers.capabilities.supportsManualCompaction |
bb.providers.provider: ProviderCapabilities.supportsManualCompaction | |
server.providers.capabilities.supportsThreadArchive |
bb.providers.provider: ProviderCapabilities.supportsThreadArchive | |
server.providers.capabilities.supportsThreadRename |
bb.providers.provider: ProviderCapabilities.supportsThreadRename | |
server.providers.strings.signInHint |
bb.providers.provider: ProviderStrings.signInHint | |
server.providers.strings.expiredHint |
bb.providers.provider: ProviderStrings.expiredHint | |
server.providers.strings.installUrl |
bb.providers.provider: ProviderStrings.installUrl | |
server.providers.strings.brandPrefix |
bb.providers.provider: ProviderStrings.brandPrefix | |
server.providers.strings.planModeCopy |
bb.providers.provider: ProviderStrings.planModeCopy | |
server.providers.strings.iconTint |
bb.providers.provider: ProviderStrings.iconTint | |
server.providers.optionDescriptor.id |
bb.providers.provider: ProviderOption.id | |
server.providers.optionDescriptor.label |
bb.providers.provider: ProviderOption.label | |
server.providers.optionDescriptor.description |
bb.providers.provider: ProviderOption.description | |
server.providers.extensionKind.item |
bb.providers.provider: ProviderExtensionKind.item | |
server.providers.extensionKind.state |
bb.providers.provider: ProviderExtensionKind.state | |
server.providers.optionsContext.threadId |
bb.providers.provider: ProviderOptionsContext.threadId | |
server.providers.optionsContext.projectId |
bb.providers.provider: ProviderOptionsContext.projectId | |
server.providers.optionsContext.model |
bb.providers.provider: ProviderOptionsContext.model | |
server.providers.optionsContext.permissionMode |
bb.providers.provider: ProviderOptionsContext.permissionMode | |
server.providers.optionsContext.promptMode |
bb.providers.provider: ProviderOptionsContext.promptMode | |
server.providers.optionsContext.settings |
bb.providers.provider: ProviderOptionsContext.settings | |
server.providers.fallbackModel.id |
bb.providers.provider: ProviderFallbackModel.id | |
server.providers.fallbackModel.displayName |
bb.providers.provider: ProviderFallbackModel.displayName | |
server.providers.fallbackModel.description |
bb.providers.provider: ProviderFallbackModel.description | |
server.providers.models.fallback |
bb.providers.provider: ProviderDeclaration.models.fallback | |
server.providers.models.scope |
bb.providers.provider: ProviderDeclaration.models.scope | |
server.providers.env.passthrough |
bb.providers.provider: ProviderDeclaration.env.passthrough | |
bridge.entry |
bb.providers.bridge host role: ProviderBridgeEntry | |
bridge.exportName |
dropped | The bb.providers.bridge host-role claim replaces the magic experimental_providerBridge export. |
bridge.context |
bb.providers.bridge host role: ProviderBridgeContext | |
bridge.definition |
bb.providers.bridge host role: ProviderBridgeDefinition | |
bridge.definition.handleLine |
bb.providers.bridge host role: ProviderBridgeDefinition.handleLine | |
bridge.definition.start |
bb.providers.bridge host role: ProviderBridgeDefinition.start | |
bridge.definition.onClose |
bb.providers.bridge host role: ProviderBridgeDefinition.onClose | |
bridge.definition.onSigterm |
bb.providers.bridge host role: ProviderBridgeDefinition.onSigterm | |
bridge.definition.onSigint |
bb.providers.bridge host role: ProviderBridgeDefinition.onSigint | |
bridge.define |
@bb/providers/bridge: defineProviderBridge() | |
bridge.parseEntry |
bb.providers.bridge host-role loader validation | The loader validates contract.json before role start. |
bridge.protocol.version |
@bb/providers/bridge: BRIDGE_PROTOCOL_VERSION | |
bridge.protocol.grammarV2 |
@bb/providers/bridge: delta grammar version 2 | Kept for negotiated compatibility. |
bridge.protocol.grammarV3 |
@bb/providers/bridge: delta grammar version 3 | Kept for negotiated compatibility. |
bridge.handshake.initialize |
@bb/providers/bridge: handshake.initialize | |
bridge.handshake.capabilities |
@bb/providers/bridge: handshake.capabilities | |
bridge.handshake.grammarVersions |
@bb/providers/bridge: handshake.grammarVersions | |
bridge.handshake.steerMode |
@bb/providers/bridge: handshake.steerMode | |
bridge.handshake.negotiateGrammar |
@bb/providers/bridge: handshake.negotiateGrammar | |
bridge.request.methods |
@bb/providers/bridge: RUNTIME_BRIDGE_METHODS | |
bridge.request.modelList |
bb.providers.bridge host role: modelList | Runtime request handlers use this message contract. |
bridge.request.providerHealth |
bb.providers.bridge host role: providerHealth | Runtime request handlers use this message contract. |
bridge.request.providerUsage |
bb.providers.bridge host role: providerUsage | Runtime request handlers use this message contract. |
bridge.request.installStatus |
bb.providers.bridge host role: installStatus | Runtime request handlers use this message contract. |
bridge.request.installRun |
bb.providers.bridge host role: installRun | Runtime request handlers use this message contract. |
bridge.request.threadStart |
bb.providers.bridge host role: threadStart | Runtime request handlers use this message contract. |
bridge.request.threadResume |
bb.providers.bridge host role: threadResume | Runtime request handlers use this message contract. |
bridge.request.threadFork |
bb.providers.bridge host role: threadFork | Runtime request handlers use this message contract. |
bridge.request.threadStop |
bb.providers.bridge host role: threadStop | Runtime request handlers use this message contract. |
bridge.request.threadLifecycle |
bb.providers.bridge host role: threadLifecycle | Runtime request handlers use this message contract. |
bridge.request.threadNameSet |
bb.providers.bridge host role: threadNameSet | Runtime request handlers use this message contract. |
bridge.request.turnStart |
bb.providers.bridge host role: turnStart | Runtime request handlers use this message contract. |
bridge.request.turnSteer |
bb.providers.bridge host role: turnSteer | Runtime request handlers use this message contract. |
bridge.request.skillsConfigure |
bb.providers.bridge host role: skillsConfigure | Runtime request handlers use this message contract. |
bridge.request.executionOptions |
@bb/providers/bridge: BridgeExecutionOptions | The type applies to thread and turn requests. |
bridge.notification.methods |
@bb/providers/bridge: BRIDGE_NOTIFICATION_METHODS | |
bridge.notification.threadIdentity |
bb.providers.bridge host role: notify.threadIdentity | |
bridge.notification.sessionReplaced |
bb.providers.bridge host role: notify.sessionReplaced | |
bridge.notification.providerRaw |
bb.providers.bridge host role: notify.providerRaw | |
bridge.notification.recovery |
bb.providers.bridge host role: notify.recovery | |
bridge.notification.error |
bb.providers.bridge host role: notify.error | |
bridge.inbound.methods |
@bb/providers/bridge: BRIDGE_RUNTIME_REQUEST_METHODS | |
bridge.inbound.toolCall |
bb.providers.host.requests: toolCall | The shared request service tracks the response. |
bridge.inbound.interaction |
bb.providers.host.requests: interaction | The shared request service tracks the response. |
bridge.delta.method |
@bb/providers/bridge: THREAD_DELTA_NOTIFICATION_METHOD | |
bridge.delta.notification |
bb.providers.bridge host role: thread/delta notification | |
bridge.delta.itemKey |
@bb/providers/bridge: DeltaItemKey | |
bridge.delta.item |
@bb/providers/bridge: DeltaItem | |
bridge.delta.itemTypes |
@bb/providers/bridge: DeltaItem["type"] | |
bridge.delta.fileChange |
@bb/providers/bridge: DeltaFileChange | |
bridge.delta.backgroundTask |
@bb/providers/bridge: BackgroundTaskItem | |
bridge.delta.fileRead |
@bb/providers/bridge: FileReadItem | |
bridge.delta.search |
@bb/providers/bridge: SearchItem | |
bridge.delta.delegation |
@bb/providers/bridge: DelegationItem | |
bridge.delta.planSteps |
@bb/providers/bridge: PlanStepsItem | |
bridge.delta.extension |
@bb/providers/bridge: ExtensionItem | |
bridge.delta.progress |
@bb/providers/bridge: DeltaProgressSnapshot | |
bridge.delta.textChannel |
@bb/providers/bridge: DeltaTextChannel | |
bridge.delta.outputChannel |
@bb/providers/bridge: DeltaOutputChannel | |
bridge.delta.noTurnFallback |
@bb/providers/bridge: DeltaNoTurnFallback | |
bridge.delta.kinds |
@bb/providers/bridge: ThreadDelta union | The union keeps all normalized delta kinds. |
bridge.recovery.hint |
@bb/providers/bridge: ProviderRecoveryHint | |
bridge.error.data |
@bb/providers/bridge: BridgeError.data | |
bridge.error.codes |
@bb/providers/bridge: BRIDGE_JSON_RPC_ERRORS | |
bridge.maintenance.health |
@bb/providers/bridge: ProviderHealth | |
bridge.maintenance.usage |
@bb/providers/bridge: ProviderUsage | |
bridge.maintenance.window |
@bb/providers/bridge: ProviderUsageWindow | |
bridge.maintenance.installStatus |
@bb/providers/bridge: ProviderInstallationStatus | |
bridge.maintenance.installAction |
@bb/providers/bridge: ProviderInstallationAction | |
bridge.maintenance.command |
@bb/providers/bridge: ProviderInstallationCommand | |
bridge.maintenance.verification |
@bb/providers/bridge: ProviderInstallationVerification | |
bridge.maintenance.runResult |
@bb/providers/bridge: ProviderInstallationRunResult | |
bridge.toolCall.request |
@bb/providers/bridge: BridgeToolCall.request | |
bridge.toolCall.response |
@bb/providers/bridge: BridgeToolCall.response | |
bridge.toolCall.decodeResponse |
bb.providers.host.requests: decodeResponse | The shared host service owns pending tool calls. |
bridge.toolCall.content |
@bb/providers/bridge: BridgeToolCall.content | |
bridge.toolCall.image |
@bb/providers/bridge: BridgeToolCall.image | |
bridge.toolCall.decodePayload |
bb.providers.host.requests: decodePayload | The shared host service owns pending tool calls. |
bridge.toolCall.buildContent |
bb.providers.host.requests: buildContent | The shared host service owns pending tool calls. |
bridge.toolCall.tracker |
bb.providers.host.requests: tracker | The shared host service owns pending tool calls. |
bridge.toolCall.tracker.forward |
bb.providers.host.requests: tracker.forward | The shared host service owns pending tool calls. |
bridge.toolCall.tracker.handle |
bb.providers.host.requests: tracker.handle | The shared host service owns pending tool calls. |
bridge.toolCall.tracker.resolve |
bb.providers.host.requests: tracker.resolve | The shared host service owns pending tool calls. |
bridge.toolCall.tracker.create |
bb.providers.host.requests: tracker.create | The shared host service owns pending tool calls. |
bridge.jsonrpc.message |
@bb/providers/bridge: JsonRpc.message | The bridge runtime owns transport decoding. |
bridge.jsonrpc.inboundRequest |
@bb/providers/bridge: JsonRpc.inboundRequest | The bridge runtime owns transport decoding. |
bridge.jsonrpc.runtimeEvent |
@bb/providers/bridge: JsonRpc.runtimeEvent | The bridge runtime owns transport decoding. |
bridge.jsonrpc.requestPlan |
@bb/providers/bridge: JsonRpc.requestPlan | The bridge runtime owns transport decoding. |
bridge.jsonrpc.noopPlan |
@bb/providers/bridge: JsonRpc.noopPlan | The bridge runtime owns transport decoding. |
bridge.jsonrpc.commandPlan |
@bb/providers/bridge: JsonRpc.commandPlan | The bridge runtime owns transport decoding. |
bridge.jsonrpc.postInitialize |
@bb/providers/bridge: JsonRpc.postInitialize | The bridge runtime owns transport decoding. |
bridge.jsonrpc.decodedToolCall |
@bb/providers/bridge: JsonRpc.decodedToolCall | The bridge runtime owns transport decoding. |
bridge.jsonrpc.decodedInteraction |
@bb/providers/bridge: JsonRpc.decodedInteraction | The bridge runtime owns transport decoding. |
bridge.jsonrpc.decodeToolCall |
@bb/providers/bridge: JsonRpc.decodeToolCall | The bridge runtime owns transport decoding. |
bridge.io.create |
bb.providers.host.requests: transport.create | The shared request service owns JSON-RPC output. |
bridge.io.lineHandler |
bb.providers.host.requests: transport.lineHandler | The shared request service owns JSON-RPC output. |
bridge.io.runRequest |
bb.providers.host.requests: transport.runRequest | The shared request service owns JSON-RPC output. |
bridge.io.sendError |
bb.providers.host.requests: transport.sendError | The shared request service owns JSON-RPC output. |
bridge.io.recoveryError |
bb.providers.host.requests: transport.recoveryError | The shared request service owns JSON-RPC output. |
bridge.lines.maxBytes |
bb.providers.host.supervisor: MAX_BRIDGE_LINE_BYTES | |
bridge.lines.read |
bb.providers.host.supervisor: readBoundedLines() | |
bridge.lines.args |
@bb/providers/host: BoundedLineReaderOptions | |
bridge.env.withoutRuntime |
bb.providers.host.supervisor: childEnv() | The shared supervisor removes runtime-only environment values. |
bridge.visibility.metadata |
@bb/providers/bridge: ProviderVisibility.metadata | |
bridge.visibility.create |
@bb/providers/bridge: ProviderVisibility.create | |
bridge.visibility.coverage |
@bb/providers/bridge: ProviderVisibility.coverage | |
bridge.visibility.description |
@bb/providers/bridge: ProviderVisibility.description | |
bridge.maintenance.resolveExecutable |
bb.providers.host.maintenance: resolveExecutable() | The shared host service removes provider-local probe code. |
bridge.maintenance.commandOutput |
bb.providers.host.maintenance: commandOutput() | The shared host service removes provider-local probe code. |
bridge.maintenance.versionFrom |
bb.providers.host.maintenance: versionFrom() | The shared host service removes provider-local probe code. |
bridge.maintenance.readCliVersion |
bb.providers.host.maintenance: readCliVersion() | The shared host service removes provider-local probe code. |
bridge.maintenance.compareVersions |
bb.providers.host.maintenance: compareVersions() | The shared host service removes provider-local probe code. |
bridge.maintenance.npmCommand |
bb.providers.host.maintenance: npmCommand() | The shared host service removes provider-local probe code. |
bridge.maintenance.formatCommand |
bb.providers.host.maintenance: formatCommand() | The shared host service removes provider-local probe code. |
bridge.maintenance.npmInstall |
bb.providers.host.maintenance: npmInstall() | The shared host service removes provider-local probe code. |
bridge.maintenance.npmLatest |
bb.providers.host.maintenance: npmLatest() | The shared host service removes provider-local probe code. |
bridge.maintenance.npmProbe |
bb.providers.host.maintenance: npmProbe() | The shared host service removes provider-local probe code. |
bridge.maintenance.npmProbeType |
@bb/providers/host: NpmGlobalPackageProbe | |
bridge.maintenance.installSource |
bb.providers.host.maintenance: installSource() | The shared host service removes provider-local probe code. |
bridge.maintenance.installationVerification |
bb.providers.host.maintenance: installationVerification() | The shared host service removes provider-local probe code. |
bridge.maintenance.downloadedInstaller |
bb.providers.host.maintenance: downloadedInstaller() | The shared host service removes provider-local probe code. |
bridge.maintenance.clampPercent |
bb.providers.host.maintenance: clampPercent() | The shared host service removes provider-local probe code. |
bridge.request.threadDiscard |
bb.providers.bridge host role: threadDiscard | Runtime request handlers use this message contract. |
bridge.request.threadArchive |
bb.providers.bridge host role: threadArchive | Runtime request handlers use this message contract. |
bridge.request.threadUnarchive |
bb.providers.bridge host role: threadUnarchive | Runtime request handlers use this message contract. |
bridge.request.threadGoalClear |
bb.providers.bridge host role: threadGoalClear | Runtime request handlers use this message contract. |
bridge.delta.inputAccepted |
@bb/providers/bridge: ThreadDelta.inputAccepted | |
bridge.delta.inputProvider |
@bb/providers/bridge: ThreadDelta.inputProvider | |
bridge.delta.turnOpen |
@bb/providers/bridge: ThreadDelta.turnOpen | |
bridge.delta.turnBoundary |
@bb/providers/bridge: ThreadDelta.turnBoundary | |
bridge.delta.itemOpen |
@bb/providers/bridge: ThreadDelta.itemOpen | |
bridge.delta.itemClose |
@bb/providers/bridge: ThreadDelta.itemClose | |
bridge.delta.itemProgress |
@bb/providers/bridge: ThreadDelta.itemProgress | |
bridge.delta.textDelta |
@bb/providers/bridge: ThreadDelta.textDelta | |
bridge.delta.textClose |
@bb/providers/bridge: ThreadDelta.textClose | |
bridge.delta.outputDelta |
@bb/providers/bridge: ThreadDelta.outputDelta | |
bridge.delta.commandSnapshot |
@bb/providers/bridge: ThreadDelta.commandSnapshot | |
bridge.delta.usage |
@bb/providers/bridge: ThreadDelta.usage | |
bridge.delta.contextWindow |
@bb/providers/bridge: ThreadDelta.contextWindow | |
bridge.delta.contextCompacted |
@bb/providers/bridge: ThreadDelta.contextCompacted | |
bridge.delta.contextCleared |
@bb/providers/bridge: ThreadDelta.contextCleared | |
bridge.delta.turnDiff |
@bb/providers/bridge: ThreadDelta.turnDiff | |
bridge.delta.threadStarted |
@bb/providers/bridge: ThreadDelta.threadStarted | |
bridge.delta.threadIdentity |
@bb/providers/bridge: ThreadDelta.threadIdentity | |
bridge.delta.threadName |
@bb/providers/bridge: ThreadDelta.threadName | |
bridge.delta.extensionState |
@bb/providers/bridge: ThreadDelta.extensionState | |
bridge.delta.rateLimits |
@bb/providers/bridge: ThreadDelta.rateLimits | |
bridge.delta.providerError |
@bb/providers/bridge: ThreadDelta.providerError | |
bridge.delta.modelFallback |
@bb/providers/bridge: ThreadDelta.modelFallback | |
bridge.delta.warning |
@bb/providers/bridge: ThreadDelta.warning | |
bridge.delta.unhandled |
@bb/providers/bridge: ThreadDelta.unhandled | |
bridge.delta.sessionEnded |
@bb/providers/bridge: ThreadDelta.sessionEnded | |
bridge.delta.sessionReset |
@bb/providers/bridge: ThreadDelta.sessionReset | |
bridge.execution.model |
@bb/providers/bridge: BridgeExecutionOptions.model | |
bridge.execution.serviceTier |
@bb/providers/bridge: BridgeExecutionOptions.serviceTier | |
bridge.execution.reasoningLevel |
@bb/providers/bridge: BridgeExecutionOptions.reasoningLevel | |
bridge.execution.promptMode |
@bb/providers/bridge: BridgeExecutionOptions.promptMode | |
bridge.execution.instructions |
@bb/providers/bridge: BridgeExecutionOptions.instructions | |
bridge.execution.envVars |
@bb/providers/bridge: BridgeExecutionOptions.envVars | |
bridge.execution.providerOptions |
@bb/providers/bridge: BridgeExecutionOptions.providerOptions | |
bridge.handshake.capabilities.sessionRestore |
@bb/providers/bridge: handshake.capabilities.sessionRestore | |
bridge.handshake.capabilities.threadArchive |
@bb/providers/bridge: handshake.capabilities.threadArchive | |
bridge.handshake.capabilities.threadRename |
@bb/providers/bridge: handshake.capabilities.threadRename | |
bridge.handshake.capabilities.threadGoalClear |
@bb/providers/bridge: handshake.capabilities.threadGoalClear | |
bridge.handshake.capabilities.fork |
@bb/providers/bridge: handshake.capabilities.fork | |
bridge.handshake.capabilities.approvalEnforcedBy |
@bb/providers/bridge: handshake.capabilities.approvalEnforcedBy | |
bridge.handshake.capabilities.grammarVersions |
@bb/providers/bridge: handshake.capabilities.grammarVersions | |
bridge.handshake.capabilities.steerMode |
@bb/providers/bridge: handshake.capabilities.steerMode | |
bridge.handshake.capabilities.skills |
@bb/providers/bridge: handshake.capabilities.skills | |
host.provider.declaration |
bb.providers.provider: ProviderDeclaration | The server and host use one declaration type. |
host.provider.declaration.id |
bb.providers.provider: ProviderDeclaration.id | |
host.provider.declaration.displayName |
bb.providers.provider: ProviderDeclaration.displayName | |
host.provider.declaration.family |
bb.providers.provider: ProviderDeclaration.family | |
host.provider.declaration.icon |
bb.providers.provider: ProviderDeclaration.icon | |
host.provider.declaration.capabilities |
bb.providers.provider: ProviderDeclaration.capabilities | |
host.provider.declaration.composerActions |
bb.providers.provider: ProviderDeclaration.composerActions | |
host.provider.declaration.experimental_bridgeOptions |
bb.providers.provider: ProviderDeclaration.bridgeOptions | The stable declaration field replaces the experimental field. |
host.provider.declaration.experimental_visibility |
bb.providers.provider: ProviderDeclaration.visibility | The stable declaration field replaces the experimental field. |
host.provider.declaration.maintenance |
bb.providers.provider: ProviderDeclaration.maintenance | |
host.provider.declaration.strings |
bb.providers.provider: ProviderDeclaration.strings | |
host.provider.declaration.serviceTiers |
bb.providers.provider: ProviderDeclaration.serviceTiers | |
host.provider.declaration.reasoningLevels |
bb.providers.provider: ProviderDeclaration.reasoningLevels | |
host.provider.declaration.extensionKinds |
bb.providers.provider: ProviderDeclaration.extensionKinds | |
host.provider.declaration.models |
bb.providers.provider: ProviderDeclaration.models | |
host.provider.declaration.env |
bb.providers.provider: ProviderDeclaration.env | |
host.provider.declaration.nativeSkillRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.skills | The native-roots object holds static skill roots. |
host.provider.declaration.nativeCommandRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.commands | The native-roots object holds static command roots. |
host.provider.declaration.resolvesNativeRoots |
bb.providers.provider: ProviderDeclaration.nativeRoots.resolveOnHost | The provider can claim the bb.providers.nativeRoots host role. |
host.provider.declaration.deriveOptions |
bb.providers.provider: Provider.deriveOptions() | Behavior moves from declaration data to the provider service. |
host.provider.capabilities |
bb.providers.provider: ProviderCapabilities | |
host.provider.strings |
bb.providers.provider: ProviderStrings | |
host.provider.option |
bb.providers.provider: ProviderOption | |
host.provider.extensionKind |
bb.providers.provider: ProviderExtensionKind | |
host.provider.optionsContext |
bb.providers.provider: ProviderOptionsContext | |
host.provider.fallbackModel |
bb.providers.provider: ProviderFallbackModel | |
host.provider.maintenance |
bb.providers.provider: ProviderMaintenance | |
host.provider.capabilities.supportsServiceTier |
bb.providers.provider: ProviderCapabilities.supportsServiceTier | |
host.provider.capabilities.supportsNativeUserQuestion |
bb.providers.provider: ProviderCapabilities.supportsNativeUserQuestion | |
host.provider.capabilities.fork |
bb.providers.provider: ProviderCapabilities.fork | |
host.provider.capabilities.supportsManualCompaction |
bb.providers.provider: ProviderCapabilities.supportsManualCompaction | |
host.provider.capabilities.supportsThreadArchive |
bb.providers.provider: ProviderCapabilities.supportsThreadArchive | |
host.provider.capabilities.supportsThreadRename |
bb.providers.provider: ProviderCapabilities.supportsThreadRename | |
host.provider.capabilities.permissionModes |
bb.providers.provider: ProviderCapabilities.permissionModes | |
host.provider.capabilities.reasoningLevels |
bb.providers.provider: ProviderCapabilities.reasoningLevels | |
host.provider.strings.signInHint |
bb.providers.provider: ProviderStrings.signInHint | |
host.provider.strings.expiredHint |
bb.providers.provider: ProviderStrings.expiredHint | |
host.provider.strings.installUrl |
bb.providers.provider: ProviderStrings.installUrl | |
host.provider.strings.brandPrefix |
bb.providers.provider: ProviderStrings.brandPrefix | |
host.provider.strings.planModeCopy |
bb.providers.provider: ProviderStrings.planModeCopy | |
host.provider.strings.iconTint |
bb.providers.provider: ProviderStrings.iconTint | |
host.provider.option.id |
bb.providers.provider: ProviderOption.id | |
host.provider.option.label |
bb.providers.provider: ProviderOption.label | |
host.provider.option.description |
bb.providers.provider: ProviderOption.description | |
host.provider.extensionKind.item |
bb.providers.provider: ProviderExtensionKind.item | |
host.provider.extensionKind.state |
bb.providers.provider: ProviderExtensionKind.state | |
host.provider.optionsContext.settings |
bb.providers.provider: ProviderOptionsContext.settings | |
host.provider.fallbackModel.id |
bb.providers.provider: ProviderFallbackModel.id | |
host.provider.fallbackModel.displayName |
bb.providers.provider: ProviderFallbackModel.displayName | |
host.provider.fallbackModel.description |
bb.providers.provider: ProviderFallbackModel.description | |
host.provider.fallbackModel.supportedReasoningEfforts |
bb.providers.provider: ProviderFallbackModel.supportedReasoningEfforts | |
host.provider.fallbackModel.defaultReasoningEffort |
bb.providers.provider: ProviderFallbackModel.defaultReasoningEffort | |
host.provider.fallbackModel.isDefault |
bb.providers.provider: ProviderFallbackModel.isDefault | |
host.provider.maintenance.health |
bb.providers.provider: ProviderMaintenance.health | |
host.provider.maintenance.usage |
bb.providers.provider: ProviderMaintenance.usage | |
host.provider.maintenance.installation |
bb.providers.provider: ProviderMaintenance.installation | |
bridge.experimental_acpAgentProbeSchema |
@bb/providers/bridge/acp: experimental_acpAgentProbeSchema | The export stays experimental. |
bridge.experimental_acpLaunchSpecSchema |
@bb/providers/bridge/acp: experimental_acpLaunchSpecSchema | The export stays experimental. |
bridge.experimental_acpProviderBridge |
@bb/providers/bridge/acp: experimental_acpProviderBridge | The adapter uses the stable bridge role. |
bridge.experimental_buildBridgeToolCallContent |
bb.providers.host.requests: buildToolContent() | The shared request service replaces the experimental helper. |
bridge.experimental_probeAcpAgent |
@bb/providers/bridge/acp: experimental_probeAcpAgent() | The export stays experimental. |
bridge.experimental_recordProviderChildIo |
bb.providers.host.supervisor: recordChildIo() | The shared supervisor owns transcript records. |
bridge.experimental_toolPresentation |
@bb/providers/bridge/acp: experimental_toolPresentation | The ACP presentation adapter stays experimental. |
bridge.interaction.secretRequest |
@bb/providers/bridge: SecretInteraction | The kernel secrets port stores the submitted value. |
bridge.providerRawEventSchema |
@bb/providers/bridge: providerRawEventSchema | |
bridge.threadDelta |
@bb/providers/bridge: ThreadDelta and threadDeltaSchema | |
host.context.experimental_retainWorker |
bb.providers.host.supervisor: retainWorker() | The shared supervisor owns worker leases. |
host.experimental_nativeRootsHostContract |
bb.providers.nativeRoots host role | The keyed role replaces the experimental host contract. |
host.experimental_providerBridge |
bb.providers.bridge host role | The keyed host-role claim replaces the magic export. |
host.experimental_resolveClaudePluginRoots |
@bb/providers/host: experimental_resolveClaudePluginRoots() | The vendor adapter stays experimental. |
host.experimental_resolveVendorPluginRoots |
@bb/providers/host: experimental_resolveVendorPluginRoots() | The vendor adapter stays experimental. |
app.contracts.PluginProviderIconRegistration |
ProviderDeclaration.icon or exact app export |
Provider identity data replaces the global icon slot. |
app.contracts.PluginProviderIconRegistration.icon |
ProviderDeclaration.icon |
A plugin can also export an exact React icon module. |
app.contracts.PluginProviderIconRegistration.providerId |
ProviderDeclaration.id |
The provider key identifies the icon owner. |
app.contracts.PluginProvidersState |
@bb/providers/app: ProviderDirectoryState |
The state reports directory status and provider records. |
app.hooks.experimental_useProviders |
@bb/providers/app: useProviders() |
The stable hook reads the active provider directory. |
app.slots.experimental_providerIcon |
dropped |
Declare icon data or export an exact provider icon component. |
host.nativeRoots.answer |
bb.providers.nativeRoots: ProviderNativeRootsRole.resolve() input |
The role call carries the validated resolver answer. |
host.nativeRoots.contract |
bb.providers.nativeRoots host role |
The keyed role replaces the experimental contract. |
host.nativeRoots.dropped |
FilteredNativeRoots.dropped |
Validation still reports each removed root. |
host.nativeRoots.filter |
bb.providers.host.declarations: filterNativeRoots() |
The shared host service validates and limits roots. |
host.nativeRoots.filtered |
FilteredNativeRoots |
The result keeps accepted roots and validation reports. |
host.nativeRoots.input |
ProviderResolvedNativeRootsInput |
The input keeps provider and workspace context. |
host.nativeRoots.output |
ProviderResolvedNativeRoots |
The output keeps normalized skill and command roots. |
host.nativeRoots.resolve |
bb.providers.nativeRoots: resolve() |
The keyed host role resolves host-specific roots. |
host.providers.namespace |
bb.providers.provider keyed service |
The service token replaces the host registration namespace. |
host.providers.register |
api.services.provide(bbProvider.key()) |
The factory scope owns provider cleanup. |
server.sdk.providers |
bb.providers service |
The named service replaces the broad SDK area. |
server.sdk.providers.list |
bb.providers service: list() |
The service returns the active provider directory. |
server.sdk.providers.models |
bb.providers service: models() |
The service resolves models through the provider winner. |
server.sdk.system.executionOptions |
bb.providers service: models() execution catalog |
The provider catalog owns execution choices. |
server.sdk.system.providerStates |
bb.providers service: list() and watch() |
Provider records carry availability and winner state. |
server.sdk.system.usageLimits |
bb.providers service: usage() |
The selected provider reports account limits. |