Provider Authoring
Build protocol-providing Aster plugin packages.
A provider is an installable plugin service that satisfies a capability
protocol. Spaces declare requires[]; providers declare provides[]; the
runtime resolves the binding.
Start From A Scaffold
bun run create:plugin -- --id sample-search --protocol aster.evidence-searchThe scaffold validates the requested protocol against
@aster/services/protocols, emits a plugin package, and prepares without
manual edits. The current provider scaffold covers aster.evidence-search; other
protocols can be authored manually once their protocol module exposes a
runtime service tag.
Provide A Protocol
import { Plugin, Provider } from "@aster/authoring/runtime"import { EVIDENCE_SEARCH_INDEX_STATE_SCHEMA_VERSION, EVIDENCE_SEARCH_RESULT_SCHEMA_VERSION, type RuntimeEvidenceSearchProviderServiceApi,} from "@aster/services/evidence-search"import { EvidenceSearchProtocol } from "@aster/services/protocols"import { Effect } from "effect"
function createEvidenceSearchProvider(): RuntimeEvidenceSearchProviderServiceApi { return { applyChanges(input) { return Effect.succeed({ generation: input.batch.generation, appliedChangeCount: input.batch.changes.length, lastAppliedCursor: input.batch.cursor, }) }, search() { return Effect.succeed({ schemaVersion: EVIDENCE_SEARCH_RESULT_SCHEMA_VERSION, generation: 0, hits: [], }) }, resetIndex(input) { return Effect.succeed({ state: { schemaVersion: EVIDENCE_SEARCH_INDEX_STATE_SCHEMA_VERSION, generation: input.generation, readiness: "rebuilding", documentCount: 0, lastAppliedCursor: null, }, }) }, getIndexState() { return Effect.succeed({ state: { schemaVersion: EVIDENCE_SEARCH_INDEX_STATE_SCHEMA_VERSION, generation: 0, readiness: "ready", documentCount: 0, lastAppliedCursor: null, }, }) }, }}
const provider = Provider.make({ providerId: "sample-search", displayName: "Sample Search", enabledByDefault: true, capabilities: [ { type: "evidence_search_provider", providerId: "sample-search", displayName: "Sample Search", protocol: EvidenceSearchProtocol.ref, }, ], ...EvidenceSearchProtocol.provide(createEvidenceSearchProvider),})
export default Plugin.make({ id: "sample-search", displayName: "Sample Search", providers: [provider],})Protocol.provide(...) wraps the plain provider interface into the internal
Effect layer. Provider authors implement the interface; the SDK owns the
Effect bridge.
Prepare And Verify
bun run prepare:pluginprepare-plugin validates protocol refs against the registry, writes
plugin.json and contributions.json, and rejects retired contract fields.
Protocol conformance kits live with the registry and should be part of a
provider package’s tests.
Authoring Rules
- Use protocol refs from
@aster/services/protocols; do not write raw contract strings. - Use
Provider.make(...)for runtime providers and put provider facets undercapabilities[]. - Decode settings with the shared authoring helpers before using them.
- Keep provider identity in provider facets; keep space needs in capability requirements.
Protocol Reference
The generated Protocol Registry lists every protocol ID, version, operation summary, settings posture, and declared authority.