Buffaly Logo
How-to

Adding self-discoverable AI providers

Register optional provider modules so a Buffaly instance can discover provider catalog rows, provider-native completion executors, and provider-specific authentication without hard-coding them into the host.

Use this with Providers and authentication, which explains provider, transport, model, reasoning, and auth concepts before you modify an installed instance.

Current provider model

Provider implementations live outside the core Buffaly development tree. A running instance discovers optional providers from provider-module assemblies installed under the authoritative runtime install root and listed in ProviderModules.json.

ConceptMeaningExamples
ProviderAI family token.openai, anthropic, xai, gemini
TransportExecution route.codex_backend, provider_native
ModelProvider-specific model name.claude-sonnet-4-5, grok-3-mini
Reasoning levelOptional model-level setting when supported.low, medium, high
Important: this page is an operational registration reference. It does not mean every Buffaly deployment has every provider enabled. OpenAI/Codex is the built-in/default catalog route; provider-native modules are installed/configured routes only when manifests, feature rows, credentials, and web/worker assemblies are present.

Shared contract requirements

External providers must implement the same shared Web.Common contracts as the target Buffaly instance.

Catalog source

IProviderCatalogSource controls whether the provider appears in the UI and catalog APIs.

Completion executor

IProviderNativeCompletionExecutor performs provider-native completions for the provider_native transport.

Auth handler

IProviderAuthHandler is optional, but OAuth-capable providers should implement it for provider-specific login flows.

The provider assembly must reference the same Buffaly.Agent.Web.Common.dll contract version as the target instance. For xAI/Grok, the provider-auth handler owns OIDC discovery and PKCE details while the host owns generic profile lifecycle and stores token bundles under data\sessions\provider-auth\<provider>.

Instance file layout

Provider modules are loaded from the runtime install root. The runtime derives this path from DB-backed Runtime Feature.InstallRootPath; there is no app-base, web-bin, worker-bin, or fallback provider-module probing.

<InstallRootPath>\lib\provider-modules\ProviderModules.json

Provider folder

A provider gets its own folder, such as Buffaly.Provider.Anthropic\Buffaly.Provider.Anthropic.dll, under lib\provider-modules.

Web and worker alignment

The web app needs catalog-source assemblies. Worker processes need completion-executor assemblies. Keep web and worker module folders aligned unless deployment tooling does this.

Copy the provider assembly and dependencies, including provider contracts, matching Buffaly.Agent.Web.Common.dll, and provider-specific DLLs. Do not store API keys in provider DLL folders, implementation files, or the provider manifest.

ProviderModules.json

ProviderModules.json registers optional provider components.

FieldRule
ProviderStable, unique provider token.
AssemblyPathRelative to the provider-modules directory.
CatalogSourceTypeNameType must implement IProviderCatalogSource.
CompletionExecutorTypeNameType must implement IProviderNativeCompletionExecutor.
AuthHandlerTypeNameOptional; OAuth-capable providers should point to an IProviderAuthHandler.
Enabledfalse keeps the module installed but undiscovered.
LoadOrderControls deterministic ordering when multiple modules are installed.

Feature settings rows

Provider credentials and model settings live in the target instance sessions database, not in source. Each provider owns a feature row in dbo.Features.

Provider-specific rows

Anthropic Feature, XAI Feature, and Gemini Feature are critical external-provider rows.

OpenAI/Codex rows

OpenAI through codex_backend also depends on Codex Auth Feature and Codex Backend Feature.

Feature settings commonly include API key or auth profile data, model names, supported reasoning levels, default reasoning level, base URL, provider API version, token limits, and optional separate debug logging. Do not print secret values in prompts, documentation, logs, or commits.

Registration steps

  1. Build the provider project in the external providers solution.
  2. Copy the provider module folder into <InstallRootPath>\lib\provider-modules.
  3. Add or update the provider entry in ProviderModules.json.
  4. Add or update the provider feature row in the target instance sessions database.
  5. Recycle only the target instance app pool.
  6. Verify the provider catalog endpoint shows the provider configured and enabled.
  7. Verify provider selection persists for a test session.
  8. Verify an end-to-end completion round trip.
Operational safety: recycle only the target app pool for the target instance. Do not kill shared Buffaly or dotnet processes as part of routine provider registration.

API verification

Use JsonWs endpoints for API-only verification before relying on UI behavior.

Catalog

Call get-provider-catalog. Confirm the provider appears in Providers, IsConfigured=true, IsEnabled=true, and has at least one transport and model.

Selection

Call set-provider-model-selection, then get-provider-selection to verify provider, transport, model, and reasoning persisted for the test session.

Completion

Call evaluate with a small smoke instruction. Expect completed status and the exact assistant response in the transcript.

Provider response contract

Provider-native executors must return Buffaly canonical items JSON in ProviderNativeCompletionResult.Raw. A successful smoke response should become a message item with role assistant, phase final_answer, output_text content, and display-message metadata.

If a third-party model returns a canonical Buffaly items payload as text or inside a closed JSON code block, the provider boundary should unwrap and validate only complete JSON objects whose root contains an items array. Otherwise, preserve ordinary text and wrap it as output_text.

Common failure modes

Provider does not appear

  • Manifest not copied to the install-root provider-modules folder.
  • Wrong assembly path or type name.
  • Mismatched Buffaly.Agent.Web.Common.dll.
  • Feature row missing, disabled, or invalid.

Provider appears unconfigured

  • Feature row exists but credentials/settings are missing.
  • Provider code reads a different feature name.
  • Settings JSON does not match the provider contract.

Selection fails

  • Provider token mismatch.
  • Model is not in the provider catalog row.
  • Reasoning level is unsupported for that model.
  • Target app pool needs recycle.

Completion fails

  • Provider DLL missing from worker folder.
  • API key invalid or provider rejects the model.
  • Response mapper does not produce canonical Buffaly items JSON.
  • Worker cannot access runtime resources due to app pool identity/profile settings.

Operator notes from validation

  • Reasoning levels are model-specific. Do not pass low, medium, or high unless the provider catalog row declares support.
  • The provider catalog can show an error while still returning configured providers. Inspect both Providers and the top-level Error field.
  • Live model availability should be verified against the provider model endpoint and with a completion smoke test.
  • App pool identity/profile settings can affect worker access to runtime resources such as named global mutexes.
Providers and authentication Manage provider models Secrets and credentials