Skip to content

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

Terminal window
bun run create:plugin -- --id sample-search --protocol aster.evidence-search

The 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

Terminal window
bun run prepare:plugin

prepare-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 under capabilities[].
  • 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.