ollama_easy 0.2.0 copy "ollama_easy: ^0.2.0" to clipboard
ollama_easy: ^0.2.0 copied to clipboard

A Flutter-friendly Ollama client with one-line prompts, typed chat, streaming, embeddings, and model helpers.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:ollama_easy/ollama_easy.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Ollama Easy Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late Ollama _ollama;
  final _controller = TextEditingController();
  final _history = <String>[];
  bool _isLoading = false;
  String _baseUrl = 'http://localhost:11434';

  @override
  void initState() {
    super.initState();
    _ollama = Ollama(baseUrl: Uri.parse(_baseUrl), defaultModel: 'qwen2.5:1.5b');
  }

  void _updateBaseUrl(String url) {
    setState(() {
      _baseUrl = url;
      _ollama.close();
      _ollama = Ollama(baseUrl: Uri.parse(_baseUrl), defaultModel: 'qwen2.5:1.5b');
      _history.add('System: Base URL updated to $_baseUrl');
    });
  }

  Future<void> _ask() async {
    final prompt = _controller.text.trim();
    if (prompt.isEmpty) return;

    setState(() {
      _isLoading = true;
      _history.add('User: $prompt');
      _controller.clear();
    });

    try {
      if (!await _ollama.isRunning()) {
        throw Exception('Ollama is not responding at $_baseUrl. Ensure the server is running and accessible.');
      }

      String fullResponse = '';
      _history.add('Ollama: ');
      final index = _history.length - 1;

      await for (final token in _ollama.askStream(prompt)) {
        fullResponse += token;
        setState(() {
          _history[index] = 'Ollama: $fullResponse';
        });
      }
    } catch (e) {
      setState(() {
        _history.add('Error: $e');
      });
    } finally {
      setState(() {
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Ollama Easy Chat'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        actions: [
          PopupMenuButton<String>(
            onSelected: _updateBaseUrl,
            itemBuilder: (context) => [
              const PopupMenuItem(
                value: 'http://localhost:11434',
                child: Text('Desktop/Physical (localhost)'),
              ),
              const PopupMenuItem(
                value: 'http://10.0.2.2:11434',
                child: Text('Android Emulator (10.0.2.2)'),
              ),
            ],
            icon: const Icon(Icons.settings),
          ),
        ],
      ),
      body: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(8),
            color: Colors.grey[200],
            child: Text('Current Server: $_baseUrl', style: const TextStyle(fontSize: 12)),
          ),
          Expanded(
            child: ListView.builder(
              padding: const EdgeInsets.all(16),
              itemCount: _history.length,
              itemBuilder: (context, index) {
                return Padding(
                  padding: const EdgeInsets.symmetric(vertical: 4),
                  child: Text(_history[index]),
                );
              },
            ),
          ),
          if (_isLoading) const LinearProgressIndicator(),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: const InputDecoration(
                      hintText: 'Type a message...',
                      border: OutlineInputBorder(),
                    ),
                    onSubmitted: (_) => _ask(),
                  ),
                ),
                const SizedBox(width: 8),
                IconButton(
                  onPressed: _isLoading ? null : _ask,
                  icon: const Icon(Icons.send),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  @override
  void dispose() {
    _ollama.close();
    _controller.dispose();
    super.dispose();
  }
}
1
likes
150
points
5
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter-friendly Ollama client with one-line prompts, typed chat, streaming, embeddings, and model helpers.

Repository (GitHub)
View/report issues

Topics

#ollama #flutter #llm #ai #local-ai

License

MIT (license)

Dependencies

http

More

Packages that depend on ollama_easy