Setup DeepSeek API with dotenv

This commit is contained in:
2026-03-27 18:38:12 +05:00
parent 26939984ad
commit bc75dc8de1
5 changed files with 92 additions and 40 deletions
+1
View File
@@ -2,6 +2,7 @@
.env .env
.env.local .env.local
.env.*.local .env.*.local
!/.env.example
# Firebase (root level) # Firebase (root level)
/google-services.json /google-services.json
+60 -23
View File
@@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:flutter_dotenv/flutter_dotenv.dart';
import '../models/task_model.dart'; import '../models/task_model.dart';
class DeepSeekService { class DeepSeekService {
@@ -29,11 +30,13 @@ class DeepSeekService {
'messages': [ 'messages': [
{ {
'role': 'system', 'role': 'system',
'content': 'You are a task planning assistant. Break down tasks into logical subtasks. Return ONLY a JSON array.', 'content':
'You are a task planning assistant. Break down tasks into logical subtasks. Return ONLY a JSON array.',
}, },
{ {
'role': 'user', 'role': 'user',
'content': 'Break down this task into 3-7 subtasks:\n\nTitle: $title\nDescription: $description\n\nReturn ONLY a JSON array with format: [{"title": "...", "estimatedHours": 0, "description": "..."}]', 'content':
'Break down this task into 3-7 subtasks:\n\nTitle: $title\nDescription: $description\n\nReturn ONLY a JSON array with format: [{"title": "...", "estimatedHours": 0, "description": "..."}]',
}, },
], ],
'temperature': 0.7, 'temperature': 0.7,
@@ -83,11 +86,13 @@ class DeepSeekService {
'messages': [ 'messages': [
{ {
'role': 'system', 'role': 'system',
'content': 'You are a task prioritization assistant. Determine task priority: low, medium, high, or urgent. Reply with ONE word only.', 'content':
'You are a task prioritization assistant. Determine task priority: low, medium, high, or urgent. Reply with ONE word only.',
}, },
{ {
'role': 'user', 'role': 'user',
'content': 'What priority should this task have?\n\nTitle: $title\nDescription: $description\nDue: ${dueDate ?? "Not specified"}\n\nReply with ONE word: low, medium, high, or urgent', 'content':
'What priority should this task have?\n\nTitle: $title\nDescription: $description\nDue: ${dueDate ?? "Not specified"}\n\nReply with ONE word: low, medium, high, or urgent',
}, },
], ],
'temperature': 0.3, 'temperature': 0.3,
@@ -97,13 +102,18 @@ class DeepSeekService {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
final content = data['choices'][0]['message']['content'].trim().toLowerCase(); final content =
data['choices'][0]['message']['content'].trim().toLowerCase();
switch (content) { switch (content) {
case 'urgent': return TaskPriority.urgent; case 'urgent':
case 'high': return TaskPriority.high; return TaskPriority.urgent;
case 'low': return TaskPriority.low; case 'high':
default: return TaskPriority.medium; return TaskPriority.high;
case 'low':
return TaskPriority.low;
default:
return TaskPriority.medium;
} }
} }
} catch (e) { } catch (e) {
@@ -134,11 +144,13 @@ class DeepSeekService {
'messages': [ 'messages': [
{ {
'role': 'system', 'role': 'system',
'content': 'You are a task description writer. Write clear, concise task descriptions in Russian. Keep it under 100 words.', 'content':
'You are a task description writer. Write clear, concise task descriptions in Russian. Keep it under 100 words.',
}, },
{ {
'role': 'user', 'role': 'user',
'content': 'Write a brief description for this task:\n\nTitle: $title\nContext: ${context ?? "No additional context"}\n\nWrite in Russian.', 'content':
'Write a brief description for this task:\n\nTitle: $title\nContext: ${context ?? "No additional context"}\n\nWrite in Russian.',
}, },
], ],
'temperature': 0.5, 'temperature': 0.5,
@@ -169,12 +181,14 @@ class DeepSeekService {
} }
try { try {
final tasksJson = tasks.map((t) => { final tasksJson = tasks
.map((t) => {
'title': t.title, 'title': t.title,
'estimatedHours': t.estimatedHours, 'estimatedHours': t.estimatedHours,
'priority': t.priority.name, 'priority': t.priority.name,
'dueDate': t.dueDate?.toIso8601String(), 'dueDate': t.dueDate?.toIso8601String(),
}).toList(); })
.toList();
final response = await http.post( final response = await http.post(
Uri.parse('$baseUrl/v1/chat/completions'), Uri.parse('$baseUrl/v1/chat/completions'),
@@ -187,7 +201,8 @@ class DeepSeekService {
'messages': [ 'messages': [
{ {
'role': 'system', 'role': 'system',
'content': 'You are a smart scheduling assistant. Distribute tasks across available days optimally. Return ONLY a JSON array.', 'content':
'You are a smart scheduling assistant. Distribute tasks across available days optimally. Return ONLY a JSON array.',
}, },
{ {
'role': 'user', 'role': 'user',
@@ -252,7 +267,8 @@ Return JSON array: [{"taskId": index, "date": "YYYY-MM-DD", "hours": 0}]
'messages': [ 'messages': [
{ {
'role': 'system', 'role': 'system',
'content': 'You are a project structure assistant. Create a mind-map structure for projects. Return ONLY a JSON array of nodes.', 'content':
'You are a project structure assistant. Create a mind-map structure for projects. Return ONLY a JSON array of nodes.',
}, },
{ {
'role': 'user', 'role': 'user',
@@ -290,13 +306,34 @@ Return JSON array of nodes with format:
} }
// Mock данные для тестирования // Mock данные для тестирования
List<Map<String, dynamic>> _mockGenerateSubtasks(String title, String description) { List<Map<String, dynamic>> _mockGenerateSubtasks(
String title, String description) {
return [ return [
{'title': 'Анализ требований', 'estimatedHours': 2, 'description': 'Изучить требования и документацию'}, {
{'title': 'Проектирование', 'estimatedHours': 3, 'description': 'Спроектировать архитектуру решения'}, 'title': 'Анализ требований',
{'title': 'Реализация', 'estimatedHours': 8, 'description': 'Написать код'}, 'estimatedHours': 2,
{'title': 'Тестирование', 'estimatedHours': 3, 'description': 'Протестировать функциональность'}, 'description': 'Изучить требования и документацию'
{'title': 'Документирование', 'estimatedHours': 2, 'description': 'Создать документацию'}, },
{
'title': 'Проектирование',
'estimatedHours': 3,
'description': 'Спроектировать архитектуру решения'
},
{
'title': 'Реализация',
'estimatedHours': 8,
'description': 'Написать код'
},
{
'title': 'Тестирование',
'estimatedHours': 3,
'description': 'Протестировать функциональность'
},
{
'title': 'Документирование',
'estimatedHours': 2,
'description': 'Создать документацию'
},
]; ];
} }
@@ -370,6 +407,6 @@ Return JSON array of nodes with format:
// Глобальный экземпляр сервиса // Глобальный экземпляр сервиса
final deepSeekService = DeepSeekService( final deepSeekService = DeepSeekService(
// API ключ можно получить на https://platform.deepseek.com // API ключ из .env файла
apiKey: null, // Добавить ключ здесь или через .env apiKey: dotenv.env['DEEPSEEK_API_KEY'],
); );
+7 -3
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'core/firebase_config.dart'; import 'core/firebase_config.dart';
import 'core/local_storage_service.dart'; import 'core/local_storage_service.dart';
import 'core/theme.dart'; import 'core/theme.dart';
@@ -8,6 +9,9 @@ import 'core/router.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
// Загрузка переменных окружения
await dotenv.load(fileName: ".env");
// Инициализация Firebase // Инициализация Firebase
await FirebaseConfig.initialize(); await FirebaseConfig.initialize();
@@ -16,13 +20,13 @@ void main() async {
runApp( runApp(
const ProviderScope( const ProviderScope(
child: NanahuiCrmApp(), child: NanaxeCrmApp(),
), ),
); );
} }
class NanahuiCrmApp extends StatelessWidget { class NanaxeCrmApp extends StatelessWidget {
const NanahuiCrmApp({super.key}); const NanaxeCrmApp({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
+8
View File
@@ -398,6 +398,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_dotenv:
dependency: "direct main"
description:
name: flutter_dotenv
sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b
url: "https://pub.dev"
source: hosted
version: "5.2.1"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
+2
View File
@@ -50,6 +50,7 @@ dependencies:
url_launcher: ^6.2.4 url_launcher: ^6.2.4
image_picker: ^1.0.7 image_picker: ^1.0.7
permission_handler: ^11.3.0 permission_handler: ^11.3.0
flutter_dotenv: ^5.1.0
# Notifications & Alarms # Notifications & Alarms
flutter_local_notifications: ^17.0.0 flutter_local_notifications: ^17.0.0
@@ -71,3 +72,4 @@ flutter:
assets: assets:
- assets/images/ - assets/images/
- assets/icons/ - assets/icons/
- .env