import 'package:flutter/material.dart'; import 'package:chat_api/chat_api.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Chat API Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const ChatDemo(), ); } } class ChatDemo extends StatefulWidget { const ChatDemo({Key? key}) : super(key: key); @override State createState() => _ChatDemoState(); } class _ChatDemoState extends State { final ChatApi _chatApi = ChatApi(); final TextEditingController _controller = TextEditingController(); final List _messages = []; String _response = ''; bool _isLoading = false; bool _isStreaming = false; @override void initState() { super.initState(); _initializeChatApi(); _listenToStream(); } Future _initializeChatApi() async { try { // 注意:请替换为你自己的API密钥 await _chatApi.initialize( apiKey: 'your-api-key-here', model: 'gpt-3.5-turbo', ); print('Chat API 初始化成功'); } catch (e) { print('初始化失败: $e'); } } void _listenToStream() { _chatApi.eventStream.listen((event) { switch (event.type) { case ChatApiEventType.token: setState(() { _response += event.content; }); break; case ChatApiEventType.complete: setState(() { _isStreaming = false; _messages.add(ChatMessage( role: MessageRole.assistant, content: _response, )); }); break; case ChatApiEventType.error: setState(() { _isStreaming = false; _response = '错误: ${event.content}'; }); break; case ChatApiEventType.functionCall: print('函数调用: ${event.content}'); break; } }); } Future _sendMessage() async { if (_controller.text.isEmpty) return; final userMessage = ChatMessage( role: MessageRole.user, content: _controller.text, ); setState(() { _messages.add(userMessage); _response = ''; _isStreaming = true; }); _controller.clear(); try { await _chatApi.sendMessageStream( messages: _messages, temperature: 0.7, ); } catch (e) { setState(() { _isStreaming = false; _response = '发送失败: $e'; }); } } Future _sendNonStreamMessage() async { if (_controller.text.isEmpty) return; final userMessage = ChatMessage( role: MessageRole.user, content: _controller.text, ); setState(() { _messages.add(userMessage); _isLoading = true; }); _controller.clear(); try { final response = await _chatApi.sendMessage( messages: _messages, temperature: 0.7, ); setState(() { _messages.add(ChatMessage( role: MessageRole.assistant, content: response, )); _isLoading = false; }); } catch (e) { setState(() { _isLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('发送失败: $e')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Chat API Demo'), actions: [ IconButton( icon: const Icon(Icons.delete), onPressed: () { setState(() { _messages.clear(); _response = ''; }); }, ), ], ), body: Column( children: [ Expanded( child: ListView.builder( padding: const EdgeInsets.all(16), itemCount: _messages.length + (_isStreaming ? 1 : 0), itemBuilder: (context, index) { if (index == _messages.length && _isStreaming) { return _buildMessage( MessageRole.assistant, _response.isEmpty ? '...' : _response, ); } final message = _messages[index]; return _buildMessage(message.role, message.content.toString()); }, ), ), if (_isLoading) const LinearProgressIndicator(), Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[100], boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, -2), ), ], ), child: Row( children: [ Expanded( child: TextField( controller: _controller, decoration: const InputDecoration( hintText: '输入消息...', border: OutlineInputBorder(), ), onSubmitted: (_) => _sendMessage(), ), ), const SizedBox(width: 8), IconButton( icon: const Icon(Icons.send), onPressed: _isStreaming || _isLoading ? null : _sendMessage, color: Colors.blue, ), IconButton( icon: const Icon(Icons.send_and_archive), onPressed: _isStreaming || _isLoading ? null : _sendNonStreamMessage, color: Colors.green, tooltip: '非流式发送', ), ], ), ), ], ), ); } Widget _buildMessage(MessageRole role, String content) { final isUser = role == MessageRole.user; return Container( margin: const EdgeInsets.only(bottom: 8), alignment: isUser ? Alignment.centerRight : Alignment.centerLeft, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isUser ? Colors.blue : Colors.grey[300], borderRadius: BorderRadius.circular(16), ), constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.7, ), child: Text( content, style: TextStyle( color: isUser ? Colors.white : Colors.black87, ), ), ), ); } @override void dispose() { _controller.dispose(); _chatApi.dispose(); super.dispose(); } }