@phosphorco/bb-plugin-perspectives
v0.2.0
Published
Independent expert help and phase-bounded perspective synthesis for bb agents.
Readme
bb-plugin-perspectives
Adds two native tools to bb agents:
helpaccepts a question and context, generates the expert prompt in a separate hidden planner, and asks one hidden helper for a concise read-only answer.gather_perspectivesaccepts 3-7 caller-supplied lenses—specific aspects or analytical angles such as"v8 performance characteristics","big-O complexity", and"duplicate work"—generates a bespoke expert prompt for each lens, launches the panel concurrently, and synthesizes every usable complete or partial outcome.
One help call creates a hidden planner and one hidden expert. One
gather_perspectives call creates one hidden planner, 3-7 concurrent hidden
workers, and one hidden synthesis thread; a malformed planner response can
consume one bounded retry. Each thread is a model invocation and carries the
cost and provider limits of its resolved execution tuple.
Execution settings
Settings expose separate phase tuples:
| Setting group | Applied to |
|---|---|
| Planner provider/model/reasoning/permission | Prompt planner and final synthesis |
| Worker provider/model/reasoning/permission | help expert and every panel worker |
Blank provider/model values and inherit selectors are explicit defaults. If
the provider is unchanged, they copy the caller's resolved tuple. If a different
provider is configured and model remains blank, Perspectives uses that
provider's declared default model; the model's default reasoning is used unless
reasoning is configured. Permission inheritance keeps the caller's permission
mode. The plugin resolves and validates both phase tuples against the caller's
environment host before it creates any hidden thread. An unavailable provider,
model, reasoning level, permission mode, or host ceiling returns a configuration
error with no partially launched panel.
Every spawn records the resolved fields as explicit inputs so bb does not re-derive a different model mid-panel. Settings affect later calls immediately; they do not mutate existing hidden threads.
Workers, planners, and synthesis are instructed to perform read-only advisory
work and not mutate files or external systems. bb 0.39 has no read-only
permission mode, so that instruction is a policy, not a technical sandbox: the
configured/inherited permission setting remains the thread's real authority
envelope and should be chosen accordingly. The plugin itself stores no result
data and contacts no external service, but the selected model/provider and its
available tools may perform network or read-only source inspection.
The panel does not stop when a majority finishes. Each worker gets the full panel phase. Unfinished workers receive a late wrap-up request, then their final or partial output is recovered at the phase boundary. One failed worker or launch does not cancel productive peers. Synthesis is still attempted when only partial evidence is available; if synthesis itself cannot finish, the tool returns its partial synthesis (if any) plus the bounded raw perspective outputs instead of discarding them.
Only the final-result thread is referenced in a successful tool response:
the synthesis thread for gather_perspectives, or the expert thread for
help. Planner and worker threads remain hidden and directly addressable for
internal diagnosis, but are not enumerated to the calling agent. If no final
result thread could be created, the fallback answer contains no internal
thread references.
Every worker is instructed to cite material factual claims inline from primary evidence it actually inspected, using clickable file-and-line links for local repository evidence and direct Markdown links for web or documentation sources. Workers distinguish supplied context and inference from independently verified facts. The synthesizer preserves and deduplicates those citations, does not invent missing citations, and reports unsupported claims as evidence gaps.
Transport compatibility
The current bb dynamic-tool path waits for one HTTP response from the plugin and applies a 300,000 ms response-body timeout. Because a synchronous tool call does not emit a body until it returns, that behaves like a five-minute end-to-end ceiling even though it is implemented as a transport timeout.
The plugin stays inside that ceiling with separate compatibility budgets:
- planner: 15 seconds total, including one retry;
- concurrent panel: 205 seconds, with wrap-up requested when 45 seconds remain;
- synthesis: 50 seconds;
- unallocated host forwarding, transport, and serialization margin: about 30 seconds.
These are phase boundaries, not a quorum policy. A timed-out worker's partial output remains evidence, its status is disclosed to the synthesizer, and the synthesis phase is reserved rather than skipped.
The long-term bb-core direction should remove the transport connection as the owner of a tool's lifetime. A durable long-running tool operation could return an operation ID immediately, publish progress or heartbeats, survive client reconnection, retain partial output, and expose explicit cancellation. Making the existing body timeout configurable or larger would be a useful smaller core fix, but it would only move the ceiling and would not make long-running tools durable.
Example:
{
"question": "Where is the performance work in this implementation?",
"context": "Focus on behavior that matters under production load.",
"lenses": [
"v8 performance characteristics",
"big-O complexity",
"duplicate work"
]
}All plugin-owned threads reuse one snapshot of the caller's project and
environment plus the prevalidated phase tuple described above. They are hidden root threads,
not children or forks, so they neither inherit the caller's provider
conversation nor report every completion and blocker into it. BB's current
parentThreadId contract is agent delegation: setting it at spawn reports
child outcomes, while setting it later queues a visible ownership-change
message. The plugin therefore does not use parent metadata as a silent grouping
mechanism.
Instead, the final-result thread contains the internal native @thread
references as inspectability metadata in its prompt, while its answer is
instructed not to repeat them. The calling agent receives only the final-result
thread reference. As a defense against prompt noncompliance, known planner and
worker thread tokens are also removed from the public result before that final
reference is appended. This gives one progressive-disclosure path to the planner
and evidence threads without injecting the whole pipeline into the caller.
The threads remain hidden from the sidebar and are explicitly instructed not
to modify state. The plugin tools are excluded from these threads to prevent
recursive panels.
Manifest
package.json is the plugin manifest. Notable fields:
bb.server— backend entry (required); optionalbb.appfor a frontend.bb.nameandbb.description— required human-facing identity.bb.branding— required; declareiconas a BB icon name or a plugin-relative compact SVG, or declarelogo.light(with optionallogo.dark). Logo assets must be relative.svg,.png, or.webpfiles.engines.bb— supported bb app version range.engines.bbPluginSdk— supported plugin SDK floor (>=0.4.8here).
The rich in-plugin logo and marketplace icon are Cole-approved PE02-A. The
package preserves the generated 1254px RGB source and the verified RGB24
nearest-neighbor 16/24/32px derivatives byte-for-byte under assets/.
Run bb plugin build before publishing git/npm installs. It writes
dist/server.js + server.meta.json (and, with bb.app, app.js /
app.css / app.meta.json). Each *.meta.json stamps SDK major/version,
artifactFormatVersion, pluginId, pluginVersion, and
builtWith so managed installs can verify the artifacts.
Install
From this directory:
bb plugin install .After editing sources, reload:
bb plugin reload perspectivesTypes & API reference
types/bb-plugin-sdk.d.ts (and types/bb-plugin-sdk-app.d.ts for the
frontend) are the full, bundled BB plugin API — tsconfig.json maps
@bb/plugin-sdk to them, so your editor and tsc see real types with no extra
install. They are readable declarations: open them for an exact signature.
The SDK surface grows with every BB release, and these are a copy. Refresh them from the BB you are running:
bb plugin types # rewrite types/ from this BB
bb plugin types --check # CI: fail when they are out of datebb plugin build and bb plugin dev refresh them for you. Ask BB to write
plugins for you: the bb-plugin-authoring skill documents the whole surface
with examples.
Confused by the API, or need something the types don't explain? Clone the BB repo and read the source: https://github.com/get-bb/bb.
