mimo_flutter_sdk_community 0.1.0 copy "mimo_flutter_sdk_community: ^0.1.0" to clipboard
mimo_flutter_sdk_community: ^0.1.0 copied to clipboard

Pure Dart client for the Xiaomi MIMO large language model API. Supports OpenAI-compatible and Anthropic-compatible endpoints, streaming, tool use, multimodal inputs, TTS, and thinking mode.

example/mimo_flutter_sdk_community_example.dart

import 'dart:io';

import 'package:mimo_flutter_sdk_community/mimo_flutter_sdk_community.dart';

Future<void> main() async {
  final apiKey = Platform.environment['MIMO_API_KEY'];
  if (apiKey == null || apiKey.isEmpty) {
    stderr.writeln('Error: Set MIMO_API_KEY environment variable.');
    exit(1);
  }

  final client = MimoClient(
    config: MimoClientConfig(apiKey: apiKey),
  );

  try {
    await openaiChat(client);
    await openaiStreamChat(client);
    await anthropicChat(client);
    await anthropicStreamChat(client);
    await openaiToolUse(client);
    await openaiWebSearch(client);
    await openaiMultimodal(client);
    await openaiTts(client);
    await openaiThinking(client);
    await anthropicThinking(client);
    await anthropicToolUse(client);
    await openaiStructuredOutput(client);
    errorHandling();
    configuration();
  } on MimoException catch (e) {
    stderr.writeln('API error: $e');
  } finally {
    client.dispose();
  }
}

/// OpenAI 格式 — 非流式对话
Future<void> openaiChat(MimoClient client) async {
  print('=== OpenAI Chat ===');

  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [
        OpenAIMessage.system('你是一个简洁的助手。'),
        OpenAIMessage.user('用一句话介绍自己'),
      ],
      temperature: 0.7,
      maxCompletionTokens: 256,
    ),
  );

  final choice = response.choices.first;
  print('assistant: ${choice.message.content}');
  print('tokens: ${response.usage?.totalTokens}');
  print('');
}

/// OpenAI 格式 — 流式对话
Future<void> openaiStreamChat(MimoClient client) async {
  print('=== OpenAI Streaming ===');

  final stream = client.chatStream(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [OpenAIMessage.user('数 1 到 5,每个数一行')],
      maxCompletionTokens: 64,
    ),
  );

  stdout.write('assistant: ');
  await for (final chunk in stream) {
    if (chunk.choices.isEmpty) continue;
    final delta = chunk.choices.first.delta;
    if (delta.content != null) {
      stdout.write(delta.content);
    }
  }
  print('\n');
}

/// Anthropic 格式 — 非流式对话
Future<void> anthropicChat(MimoClient client) async {
  print('=== Anthropic Chat ===');

  final response = await client.messages(
    AnthropicMessagesRequest(
      model: MimoModel.mimoV2Pro.id,
      maxTokens: 256,
      system: '你是一个简洁的助手。',
      messages: [AnthropicMessage.user('用一句话介绍自己')],
      temperature: 0.7,
    ),
  );

  final textBlock = response.content.whereType<AnthropicTextContent>().first;
  print('assistant: ${textBlock.text}');
  print('tokens: ${response.usage?.outputTokens}');
  print('');
}

/// Anthropic 格式 — 流式对话
Future<void> anthropicStreamChat(MimoClient client) async {
  print('=== Anthropic Streaming ===');

  final stream = client.messagesStream(
    AnthropicMessagesRequest(
      model: MimoModel.mimoV2Pro.id,
      maxTokens: 64,
      messages: [AnthropicMessage.user('数 1 到 5,每个数一行')],
    ),
  );

  stdout.write('assistant: ');
  await for (final event in stream) {
    if (event is AnthropicContentBlockDeltaEvent) {
      final delta = event.delta;
      if (delta is AnthropicTextDelta) {
        stdout.write(delta.text);
      }
    }
  }
  print('\n');
}

/// OpenAI 格式 — 工具调用 (Function Calling)
Future<void> openaiToolUse(MimoClient client) async {
  print('=== OpenAI Tool Use ===');

  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [OpenAIMessage.user('北京今天天气怎么样?')],
      tools: [
        OpenAITool.function(
          name: 'get_weather',
          description: '获取指定城市的当前天气',
          parameters: {
            'type': 'object',
            'properties': {
              'city': {'type': 'string', 'description': '城市名称'},
            },
            'required': ['city'],
          },
        ),
      ],
      toolChoice: const OpenAIToolChoice.auto(),
      maxCompletionTokens: 256,
    ),
  );

  final choice = response.choices.first;
  if (choice.message.toolCalls != null) {
    for (final call in choice.message.toolCalls!) {
      print('tool call: ${call.function.name}(${call.function.parsedArguments})');
    }
  } else {
    print('assistant: ${choice.message.content}');
  }
  print('');
}

/// OpenAI 格式 — Web Search
Future<void> openaiWebSearch(MimoClient client) async {
  print('=== OpenAI Web Search ===');

  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [OpenAIMessage.user('今天有什么重要新闻?')],
      tools: [OpenAITool.webSearch()],
      maxCompletionTokens: 512,
    ),
  );

  print('assistant: ${response.choices.first.message.content}');
  print('');
}

/// OpenAI 格式 — 图片理解 (Multimodal)
Future<void> openaiMultimodal(MimoClient client) async {
  print('=== OpenAI Multimodal ===');

  // Image URL
  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Omni.id,
      messages: [
        OpenAIMessage.userContent([
          OpenAIMessageContent.text('描述这张图片'),
          OpenAIMessageContent.imageUrl('https://example.com/photo.jpg'),
        ]),
      ],
      maxCompletionTokens: 256,
    ),
  );

  print('assistant: ${response.choices.first.message.content}');

  // Base64 image(需要先读取本地文件)
  // final base64Data = base64Encode(await File('photo.png').readAsBytes());
  // final response2 = await client.chat(
  //   OpenAIChatRequest(
  //     model: MimoModel.mimoV2Omni.id,
  //     messages: [
  //       OpenAIMessage.userContent([
  //         OpenAIMessageContent.text('描述这张图片'),
  //         OpenAIMessageContent.imageBase64(base64Data, 'image/png'),
  //       ]),
  //     ],
  //     maxCompletionTokens: 256,
  //   ),
  // );
  print('');
}

/// OpenAI 格式 — 文字转语音 (TTS)
Future<void> openaiTts(MimoClient client) async {
  print('=== OpenAI TTS ===');

  final audioBytes = await client.tts(
    input: '你好,这是 MiMo 语音合成示例。',
    voice: TtsVoice.mimoDefault,
    format: TtsAudioFormat.wav,
  );

  await File('output.wav').writeAsBytes(audioBytes);
  print('Audio saved to output.wav (${audioBytes.length} bytes)');
  print('');
}

/// OpenAI 格式 — 思考模式 (Thinking Mode)
Future<void> openaiThinking(MimoClient client) async {
  print('=== OpenAI Thinking ===');

  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [OpenAIMessage.user('25 * 47 等于多少?请逐步推理。')],
      thinking: OpenAIThinkingConfig.enabled(),
      maxCompletionTokens: 1024,
    ),
  );

  final message = response.choices.first.message;
  if (message.reasoningContent != null) {
    print('thinking: ${message.reasoningContent}');
  }
  print('assistant: ${message.content}');
  print('');
}

/// Anthropic 格式 — 思考模式 (Thinking Mode)
Future<void> anthropicThinking(MimoClient client) async {
  print('=== Anthropic Thinking ===');

  final response = await client.messages(
    AnthropicMessagesRequest(
      model: MimoModel.mimoV2Pro.id,
      maxTokens: 2048,
      messages: [AnthropicMessage.user('25 * 47 等于多少?请逐步推理。')],
      thinking: AnthropicThinkingConfig.enabled(budgetTokens: 1024),
    ),
  );

  for (final block in response.content) {
    if (block is AnthropicThinkingContent) {
      print('thinking: ${block.thinking}');
    } else if (block is AnthropicTextContent) {
      print('assistant: ${block.text}');
    }
  }
  print('');
}

/// Anthropic 格式 — 工具调用 (Function Calling)
Future<void> anthropicToolUse(MimoClient client) async {
  print('=== Anthropic Tool Use ===');

  final response = await client.messages(
    AnthropicMessagesRequest(
      model: MimoModel.mimoV2Pro.id,
      maxTokens: 256,
      messages: [AnthropicMessage.user('北京今天天气怎么样?')],
      tools: [
        const AnthropicTool(
          name: 'get_weather',
          description: '获取指定城市的当前天气',
          inputSchema: {
            'type': 'object',
            'properties': {
              'city': {'type': 'string', 'description': '城市名称'},
            },
            'required': ['city'],
          },
        ),
      ],
      toolChoice: const AnthropicToolChoice.auto(),
    ),
  );

  for (final block in response.content) {
    if (block is AnthropicToolUseContent) {
      print('tool call: ${block.name}(${block.input})');
    } else if (block is AnthropicTextContent) {
      print('assistant: ${block.text}');
    }
  }
  print('');
}

/// OpenAI 格式 — 结构化输出 (Structured Output)
Future<void> openaiStructuredOutput(MimoClient client) async {
  print('=== OpenAI Structured Output ===');

  final response = await client.chat(
    OpenAIChatRequest(
      model: MimoModel.mimoV2Pro.id,
      messages: [
        OpenAIMessage.user(
          '列出 3 种编程语言。返回 JSON: '
          '{"languages": [{"name": "...", "year": 1990}]}',
        ),
      ],
      responseFormat: const OpenAIResponseFormat.jsonObject(),
      maxCompletionTokens: 256,
    ),
  );

  final content = response.choices.first.message.content;
  print('assistant: $content');
  print('');
}

/// 错误处理 — 各异常类型的 catch 示例
void errorHandling() {
  print('=== Error Handling ===');

  // 演示各异常类型的捕获方式
  try {
    throw const MimoAuthenticationException('Invalid API key');
  } on MimoAuthenticationException catch (e) {
    print('MimoAuthenticationException: ${e.message}');
  }

  try {
    throw const MimoRateLimitException(
      'Rate limited',
      retryAfter: Duration(seconds: 60),
    );
  } on MimoRateLimitException catch (e) {
    print('MimoRateLimitException: ${e.message}, retryAfter: ${e.retryAfter}');
  }

  try {
    throw const MimoApiException('Bad request', statusCode: 400);
  } on MimoApiException catch (e) {
    print('MimoApiException: ${e.message} (${e.statusCode})');
  }

  try {
    throw const MimoServerException('Internal server error', statusCode: 500);
  } on MimoServerException catch (e) {
    print('MimoServerException: ${e.message} (${e.statusCode})');
  }

  try {
    throw const MimoNetworkException('Connection timeout');
  } on MimoNetworkException catch (e) {
    print('MimoNetworkException: ${e.message}');
  }

  print('');
}

/// 配置 — MimoClientConfig 全参数展示
void configuration() {
  print('=== Configuration ===');

  // 全参数配置示例
  final _ = MimoClientConfig(
    apiKey: 'your-api-key',
    baseUrl: 'https://api.xiaomimimo.com',
    defaultFormat: MimoApiFormat.openai,
    connectTimeout: const Duration(seconds: 30),
    receiveTimeout: const Duration(seconds: 120),
    headers: {'X-Custom': 'value'},
    // httpClient: customHttpClient, // 可选:自定义 HTTP client
  );

  print('MimoClientConfig created with all parameters');
  print('');
}
2
likes
130
points
7
downloads

Documentation

API reference

Publisher

verified publisherzhangdamao.com

Weekly Downloads

Pure Dart client for the Xiaomi MIMO large language model API. Supports OpenAI-compatible and Anthropic-compatible endpoints, streaming, tool use, multimodal inputs, TTS, and thinking mode.

Repository (GitHub)
View/report issues

Topics

#api-client #llm #openai #anthropic #streaming

License

unknown (license)

Dependencies

http

More

Packages that depend on mimo_flutter_sdk_community