Skip to main content

Ollama

Ollama runs text models on your own machine, so there is no API key and no per-token cost. OllamaTextClient talks to a local Ollama daemon over its /api/chat endpoint and returns a text GenerationResult like any other provider.

By default the client posts to http://localhost:11434/api/chat and uses the llama3.1 model. Pull the model once with ollama pull llama3.1, make sure the daemon is running, and you are ready to generate.

Simple completion

This makes a real request to a local Ollama. The model must already be pulled (ollama pull llama3.1).

import 'package:ai_abstracted/ai_abstracted.dart';

Future<void> main() async {
final client = OllamaTextClient(
credentials: const ProviderCredentials(apiKey: ''),
);

final result = await client.generateText(
const TextRequest(prompt: 'Write one sentence about local models.'),
);

print(result.text);
}

The apiKey is empty because Ollama does not authenticate. result.text decodes the response bytes as UTF-8 for you.

System prompt, history, temperature, and JSON

You can frame the model with a system prompt, carry prior turns in history, set temperature, and ask for JSON output. Passing a jsonSchema sets Ollama's format to json, so the model returns a parseable JSON string. The daemon enforces valid JSON, but it does not validate against the schema shape, so treat the schema as a hint and still parse defensively.

import 'dart:convert';

import 'package:ai_abstracted/ai_abstracted.dart';

Future<void> main() async {
// Point at a remote Ollama host with baseUrl; drop it to use localhost.
final client = OllamaTextClient(
credentials: ProviderCredentials(
apiKey: '',
baseUrl: Uri.parse('http://host:11434'),
),
);

final result = await client.generateText(
TextRequest(
prompt: 'Give me the capital as JSON.',
model: 'llama3.1',
system: 'You answer with strict JSON only.',
temperature: 0.2,
history: const [
TextMessage.user('We are talking about France.'),
TextMessage.assistant('Understood, France it is.'),
],
jsonSchema: const {
'type': 'object',
'properties': {
'capital': {'type': 'string'},
},
},
),
);

final data = jsonDecode(result.text) as Map<String, Object?>;
print(data['capital']);
}

The baseUrl override keeps the /api/chat path and swaps the host, so you can run the daemon on another machine on your network and point every request there.

Tips

  • No key, no cost. Everything runs on your machine, which makes Ollama a good fit for offline development and for tests that want a real model instead of a fake.
  • The model has to exist locally. ollama pull <model> first, then pass that name as TextRequest.model. The default is llama3.1.
  • Start the daemon before you generate. OllamaTextClient does not launch Ollama for you.

Errors

When the daemon is not running or the host is unreachable, the client raises AiTransientException. That is the retryable error class, so a short delay and a retry is reasonable once you confirm the daemon is up. See error handling for the full exception set.

See also

  • Mistral for a hosted text provider with the same request shape
  • Credentials for the keyless and baseUrl setup