Skip to content

Commit

Permalink
Add Ollama provider
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmigloz committed Dec 17, 2024
1 parent c519510 commit c5ac807
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 1 deletion.
136 changes: 136 additions & 0 deletions lib/src/providers/implementations/ollama_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import 'dart:convert';

import 'package:flutter/foundation.dart';
import 'package:ollama_dart/ollama_dart.dart';

import '../../llm_exception.dart';
import '../interface/attachments.dart';
import '../interface/chat_message.dart';
import '../interface/llm_provider.dart';
import '../interface/message_origin.dart';

/// A provider for Ollama's language models.
///
/// This provider implements the [LlmProvider] interface to integrate Ollama's
/// locally hosted models into the chat interface.
class OllamaProvider extends LlmProvider with ChangeNotifier {
/// Creates an Ollama provider instance.
///
/// [baseUrl] defaults to 'http://localhost:11434/api' if not provided.
/// [model] specifies which Ollama model to use (e.g., 'llama3.2-vision', 'gemma, etc.)
OllamaProvider({
String? baseUrl,
Map<String, String>? headers,
Map<String, String>? queryParams,
required String model,
}) : _client = OllamaClient(
baseUrl: baseUrl,
headers: headers,
queryParams: queryParams,
),
_model = model,
_history = [];

final OllamaClient _client;
final String _model;
final List<ChatMessage> _history;

@override
Stream<String> generateStream(
String prompt, {
Iterable<Attachment> attachments = const [],
}) async* {
final messages = _mapToOllamaMessages([
ChatMessage.user(prompt, attachments),
]);

yield* _generateStream(messages);
}

@override
Stream<String> sendMessageStream(
String prompt, {
Iterable<Attachment> attachments = const [],
}) async* {
final userMessage = ChatMessage.user(prompt, attachments);
final llmMessage = ChatMessage.llm();
_history.addAll([userMessage, llmMessage]);

final messages = _mapToOllamaMessages(_history);
final stream = _generateStream(messages);

// don't write this code if you're targeting the web until this is fixed:
// https://github.com/dart-lang/sdk/issues/47764
// await for (final chunk in stream) {
// llmMessage.append(chunk);
// yield chunk;
// }
yield* stream.map((chunk) {
llmMessage.append(chunk);
return chunk;
});

notifyListeners();
}

@override
Iterable<ChatMessage> get history => _history;

@override
set history(Iterable<ChatMessage> history) {
_history.clear();
_history.addAll(history);
notifyListeners();
}

Stream<String> _generateStream(List<Message> messages) async* {
final stream = _client.generateChatCompletionStream(
request: GenerateChatCompletionRequest(
model: _model,
messages: messages,
),
);

yield* stream.map((res) => res.message.content);
}

List<Message> _mapToOllamaMessages(List<ChatMessage> messages) {
return messages.map((message) {
switch (message.origin) {
case MessageOrigin.user:
if (message.attachments.isEmpty) {
return Message(
role: MessageRole.user,
content: message.text ?? '',
);
}

return Message(
role: MessageRole.user,
content: message.text ?? '',
images: [
for (final attachment in message.attachments)
if (attachment is ImageFileAttachment)
base64Encode(attachment.bytes)
else
throw LlmFailureException(
'Unsupported attachment type: $attachment',
),
],
);

case MessageOrigin.llm:
return Message(
role: MessageRole.assistant,
content: message.text ?? '',
);
}
}).toList(growable: false);
}

@override
void dispose() {
_client.endSession();
super.dispose();
}
}
1 change: 1 addition & 0 deletions lib/src/providers/providers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

export 'implementations/echo_provider.dart';
export 'implementations/gemini_provider.dart';
export 'implementations/ollama_provider.dart';
export 'implementations/vertex_provider.dart';
export 'interface/attachments.dart';
export 'interface/chat_message.dart';
Expand Down
3 changes: 2 additions & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ dependencies:
google_generative_ai: ^0.4.3
image_picker: ^1.1.2
mime: ^2.0.0
ollama_dart: ^0.2.2+1
universal_platform: ^1.1.0
uuid: ^4.4.2
waveform_recorder: ^1.3.0

dev_dependencies:
flutter_lints: ^5.0.0
flutter_test:
Expand Down

0 comments on commit c5ac807

Please sign in to comment.