Skip to content

Tool Providers

Configure and use tool providers.

Overview

Tool providers are runtime implementations of tool interfaces. The same Lumen code works with different providers by changing configuration.

Provider Types

OpenAI-Compatible

Works with OpenAI, Ollama, vLLM, and compatible APIs:

toml
[providers]
llm.chat = "openai-compatible"

[providers.config.openai-compatible]
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
default_model = "gpt-4o"

Configuration Options

OptionDescriptionDefault
base_urlAPI base URLRequired
api_key_envEnvironment variable for API keyRequired
default_modelDefault model IDgpt-4
organizationOpenAI organization IDNone
timeout_msRequest timeout30000
max_retriesMaximum retries3

Ollama (Local)

toml
[providers]
llm.chat = "openai-compatible"

[providers.config.openai-compatible]
base_url = "http://localhost:11434/v1"
default_model = "llama3"
# No API key needed

Anthropic

toml
[providers]
llm.chat = "anthropic"

[providers.config.anthropic]
api_key_env = "ANTHROPIC_API_KEY"
default_model = "claude-3-opus-20240229"

HTTP Provider

Built-in HTTP client:

toml
[providers]
http.get = "builtin-http"
http.post = "builtin-http"

[providers.config.builtin-http]
max_redirects = 5
timeout_ms = 30000
user_agent = "Lumen/1.0"

PostgreSQL

toml
[providers]
postgres.query = "postgres"

[providers.config.postgres]
connection_string_env = "DATABASE_URL"
pool_size = 10

Provider Interface

Every provider implements:

rust
trait ToolProvider {
    fn name() -> String;
    fn version() -> String;
    fn schema() -> ToolSchema;
    fn call(input: Json) -> result;
    fn effects() -> list[EffectKind];
    fn capabilities() -> list[Capability>;
}

Capabilities

Providers advertise capabilities:

CapabilityDescription
TextGenerationBasic text generation
ChatMulti-turn conversation
EmbeddingText embeddings
VisionImage processing
ToolUseFunction calling
StructuredOutputJSON schema output
StreamingStreaming responses

Check capabilities:

rust
provider.has_capability(Capability::Vision)

Retry Policy

Configure retry behavior:

toml
[providers.config.openai-compatible.retry]
max_retries = 3
base_delay_ms = 100
max_delay_ms = 10000
retry_on = ["RateLimit", "Timeout", "ProviderUnavailable"]

Error Handling

Error Types

ErrorDescription
NotFoundTool not registered
InvalidArgsInvalid arguments
ExecutionFailedGeneral failure
RateLimitRate limited
AuthErrorAuth failure
ModelNotFoundModel unavailable
TimeoutRequest timeout
ProviderUnavailableService down

Handling in Code

lumen
cell safe_call(prompt: String) -> result[String, String] / {llm}
  let result = Chat(prompt: prompt)
  
  match result
    response: String -> return ok(response)
    error: ToolError ->
      match error
        RateLimit(retry_after) -> return err("Rate limited, retry in {retry_after}ms")
        Timeout(elapsed, limit) -> return err("Timed out after {elapsed}ms")
        AuthError(msg) -> return err("Auth failed: {msg}")
        _ -> return err("Failed: {error}")
      end
  end
end

Multiple Providers

Configure multiple providers:

toml
[providers]
llm.chat = "openai-compatible"
llm.embed = "openai-compatible-embed"

[providers.config.openai-compatible]
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
default_model = "gpt-4o"

[providers.config.openai-compatible-embed]
base_url = "https://api.openai.com/v1"
api_key_env = "OPENAI_API_KEY"
default_model = "text-embedding-3-small"

Provider Selection

Choose providers at runtime:

toml
[providers]
llm.chat = "${LLM_PROVIDER:-openai-compatible}"

Then:

bash
# Use default
lumen run app.lm.md

# Use different provider
LLM_PROVIDER=anthropic lumen run app.lm.md

Best Practices

  1. Use environment variables — Never hardcode secrets
  2. Set timeouts — Prevent hanging
  3. Configure retries — Handle transient failures
  4. Test with local — Use Ollama for development
  5. Monitor usage — Track costs and performance

Next Steps

MIT Licensed