Add a transcription provider¶
Provider installation is server-owned. A context may select only a provider
and model returned by ContextService.GetModelCatalog; it cannot provide a
network endpoint, Cloud Run audience, or credential. Those values come from
trusted runtime configuration, and credentials are resolved from Secret Manager in the cloud or Vault locally for the
authenticated user or workspace.
If the transport, credential schema, and endpoint policy already exist, follow add a transcription model instead.
To add a provider:
- Add or reuse a byte-oriented client implementing
htr/pkg/providers.Client. Provider HTTP payloads, authentication header placement, response parsing, byte ceilings, redirect rejection, and typed redacted errors belong in the general-purpose HTR repository. Scribe must not add a vendor HTTP implementation underinternal/. Native local implementations such as Tesseract may use aproviderregistry.Executionmode; remote providers use an HTR client factory. - Add one descriptor in
internal/providerregistry/registry.go. That single record owns the identifier, label, factory, execution mode, configured models/default, context capabilities, request/response limits, retry policy, credential schema, and endpoint policy. Do not add a second provider switch or default-model table elsewhere. - Add administrator-owned endpoint, audience, model, deadline, retry, and
response-limit settings to both
config.yamlcopies and their validation. Recheck the vendor lifecycle documentation whenever a default changes, and remove retired model identifiers from the allowlist. A syntactically valid model identifier is not evidence that the vendor still serves it. - Resolve credentials through the existing provider-secret store. Durable
upload, reprocess, and worker jobs use only administrator-managed workspace
credentials; personal credentials are intentionally limited to interactive
editor enrichment and are never inferred from a job creator. Do not
accept an API key, base URL, or audience from
Contextor an item payload. Attach request credentials withproviderregistry.WithCredential; the HTR client's credential callback resolves them through its immutable descriptor'sCredentialmethod. Never copy a request credential into a process environment variable: concurrent workspaces must remain isolated.newOpenAIClientis the Scribe policy wiring reference; the request implementation itself is in HTR. - Map HTR's
providers.Errorcategories into Scribe's stable audit/job error vocabulary. Never inspect response bodies or provider error strings to decide retry behavior, and keep request/response body capture disabled. - Add Scribe registry-policy tests and HTR client contract tests with a local HTTP server for success, timeout, oversized/malformed response, redirect rejection, retryable failure, secret redaction, and concurrent credential isolation.
- Add a worker integration test proving a stale job lease or stale AnnotationPage revision cannot overwrite a newer correction.
The context UI must discover the new choice from GetModelCatalog. If the
addition requires a provider switch in a handler, service, or browser module,
the decision belongs in the registry descriptor/factory instead. The public
catalog is produced only by Registry.Catalog; its type deliberately omits
endpoint URLs, audiences, factories, retry details, and credential field names.
Segmentation engines follow the same rule. Register the engine descriptor and
factory in providerregistry, add its approved selection IDs to trusted runtime
configuration, and let Registry.NewSegmentor resolve exact server-owned
origins. Remote /v1/segment calls use
htr/pkg/remoteocr; all callers share Scribe's internal/gcpidentity token
source. The source accepts only a validated service-account JSON or the
keyless, non-delegated impersonation ADC shape named by
GOOGLE_APPLICATION_CREDENTIALS, binds and caches a provider per exact
audience, and uses metadata only when no credential file is configured.
Authenticated audiences are canonical HTTPS origins without a trailing slash
or path, so preflight and request-time cache keys are identical. Scribe
owns only image preparation and conversion to its WordBox domain type.
Remote failures remain failures and are never hidden by a different engine.
Unknown selection IDs are rejected; they never silently fall back to a
different model.
Reusable evaluation belongs in htr/pkg/metrics. Scribe may define the text
normalization associated with a persisted metric, but it must call HTR for
Unicode character distance, CER/WER, similarity, and word alignment so model
benchmarking and production correction metrics share one implementation.
Operational metadata is read through the generated Connect
ItemService.ListItemProviderCallAudits RPC. Keep this as the single audit
query surface; do not add a parallel REST audit route or capture prompts,
provider requests, or provider responses.