Custom Providers
Dartantic allows you to extend its functionality by creating your own custom providers. This is useful for integrating with LLM services that are not yet natively supported, for creating mock providers for testing purposes or for amazing your friends at parties.
The process involves two main steps:
- Implementing the
Provider
andModel
interfaces. - Registering your custom provider in the
Agent.providers
table (optional).
Once registered, your custom provider can be used just like any of the built-in
providers. If you don't register your provider, you can still use it by passing
the provider name to the Agent.provider()
constructor.
Example: Creating and Using a Custom Echo Provider
Here's a complete example of how to create a simple EchoProvider
that just
echos back the prompt it receives.
First, define your Model
and Provider
implementations:
import 'package:dartantic_ai/dartantic_ai.dart';
/// A simple model that echos back the prompt.
class EchoModel implements Model {
@override
Set<ProviderCaps> get caps => {ProviderCaps.textGeneration};
@override
String get generativeModelName => 'echo';
@override
String get embeddingModelName => '';
@override
Stream<AgentResponse> runStream({
required String prompt,
Iterable<Message> messages = const [],
Iterable<Part> attachments = const [],
}) async* {
yield AgentResponse(
output: prompt,
messages: [
...messages,
Message.user([TextPart(prompt)]),
Message.model([TextPart(prompt)]),
],
);
}
@override
Future<Float64List> createEmbedding(String text, {EmbeddingType? type}) {
throw UnsupportedError('EchoModel does not support embeddings.');
}
}
/// A custom provider that serves the [EchoModel].
class EchoProvider implements Provider {
@override
String get name => 'echo';
@override
Set<ProviderCaps> get caps => {ProviderCaps.textGeneration};
@override
Model createModel(ModelSettings settings) => EchoModel();
@override
Future<Iterable<ModelInfo>> listModels() async => [
ModelInfo(
providerName: name,
name: 'echo',
kinds: const {ModelKind.chat},
stable: true,
),
];
}
Next, register your provider and use it to create an Agent
:
void main() async {
// 1. Register your custom provider in the static table.
Agent.providers['echo'] = (_) => EchoProvider();
// 2. Create an agent using your provider's name.
final agent = Agent('echo');
final response = await agent.run('Hello, custom provider!');
// 3. Verify that it works.
print(response.output); // Output: Hello, custom provider!
print(agent.model); // Output: echo:echo
}
For a complete implementation, see custom_provider.dart.