Provider Configuration

ModelProviderHandle scopes model-management operations to one workspace and one capability family. It does not create a provider resource. Instead, it exposes backend discovery and creation, address probing, and the router entry point.

Select a provider family

llm = workspace.llm_provider()
embedding = workspace.embedding_provider()
parser = workspace.parser_provider()

print(llm.kind)  # llm
llm := workspace.LLMProvider()
embedding := workspace.EmbeddingProvider()
parser := workspace.ParserProvider()

fmt.Println(llm.Kind()) // llm

All three entry points return the same handle type, but their supported configuration differs:

Family

Main backend configuration

Address probe

LLM

Models, address, API key, timeout, provider type, and reasoning-control protocol

Supported

Embedding

Models, address, API key, timeout, and provider type

Supported

Parser

Supported MIME types, address, API key, timeout, and provider type

Not supported by probe_address / ProbeAddress

The table lists options exposed by the SDK; it does not define valid protocol strings, model names, or MIME types. Obtain those values from the target service or the current product UI.

Discover and bind backends

backends() / Backends() returns the backends in the selected provider family. IDs from this result are authoritative inputs for updates, endpoint operations, and deletion.

result = llm.backends()
for backend in result.backends:
    print(backend.id, backend.name, list(backend.models))

# Bind an ID obtained from a list/create result or explicit user input.
backend = llm.backend(str(result.backends[0].id))
current = backend.info()
result, err := llm.Backends(ctx)
if err != nil {
    return err
}
for _, backend := range result.GetBackends() {
    fmt.Println(backend.GetId(), backend.GetName(), backend.GetModels())
}

backend, err := llm.Backend(strconv.FormatInt(result.GetBackends()[0].GetId(), 10))
if err != nil {
    return err
}
current, err := backend.Info(ctx)

backend(id) / Backend(id) only constructs a handle; it does not prove that the resource exists. Never invent an ID or substitute a list index for a backend ID.

Probe an address before creation

LLM and Embedding providers can query the model list exposed by a remote service before creating a backend. API keys are sensitive: read them from a secret store or environment variable, and do not print or commit them.

import os
import moi_product_sdk as sdk

models = llm.probe_address(
    model_endpoint,
    sdk.with_provider_backend_api_key(os.environ["MODEL_API_KEY"]),
)
print(list(models.models))
models, err := llm.ProbeAddress(
    ctx,
    modelEndpoint,
    sdk.WithProviderBackendAPIKey(os.Getenv("MODEL_API_KEY")),
)
if err != nil {
    return err
}
fmt.Println(models.GetModels())

A successful probe only means that the address returned a model list at that time. It creates no resource and does not replace post-creation verification. Parser providers reject this operation as unsupported.

Create a backend

The create call returns both a ProviderBackendHandle and the created ProviderBackend. LLM and Embedding backends require a model list; Parser backends use supported MIME types instead.

backend, created = llm.create_backend(
    backend_name,
    sdk.with_provider_backend_address(model_endpoint),
    sdk.with_provider_backend_api_key(os.environ["MODEL_API_KEY"]),
    sdk.with_provider_backend_models(*selected_models),
    sdk.with_provider_backend_timeout_seconds(60),
)
print(backend.id, created.name)
backend, created, err := llm.CreateBackend(
    ctx,
    backendName,
    sdk.WithProviderBackendAddress(modelEndpoint),
    sdk.WithProviderBackendAPIKey(os.Getenv("MODEL_API_KEY")),
    sdk.WithProviderBackendModels(selectedModels...),
    sdk.WithProviderBackendTimeoutSeconds(60),
)
if err != nil {
    return err
}
fmt.Println(backend.ID(), created.GetName())

Python and Go also provide the workspace-level setup_llm_backend / SetupLLMBackend convenience method. It requires a name, address, and model list, and returns a combined backend-and-endpoint result. Use the provider handle when you need to inspect each configuration step separately.

Errors and permissions

  • Empty names, IDs, or addresses, and a missing required model list, are rejected by the SDK or service.

  • Address and backend probes call an external model service. Apply a bounded timeout and avoid unbounded retries.

  • Create, update, and delete operations require the relevant workspace model-resource permissions.

  • service() / Service() is a route-aligned escape hatch. Prefer handle methods for application code and use the lower-level service only for confirmed gaps in the Product SDK facade.

See Backends and Endpoints for fields and lifecycle operations, and Router Configuration for provider-level routing.