f1e0f6b5ef
- Add complete server infrastructure with Gitea, API, PostgreSQL - Implement Obsidian-compatible markdown mindmap converter - Add Flutter service for server synchronization - Configure GitHub Actions for automated build and deploy - Add production docker-compose with health checks - Include VPS setup and deployment scripts - Add comprehensive deployment documentation
350 lines
13 KiB
Dart
350 lines
13 KiB
Dart
import 'dart:convert';
|
||
import 'package:http/http.dart' as http;
|
||
|
||
// Простой тест DeepSeek API без Flutter зависимостей
|
||
void main() async {
|
||
const apiKey = 'sk-6600b6bee68745aa88b076b0c3393638';
|
||
const baseUrl = 'https://api.deepseek.com';
|
||
|
||
print('🧪 Тестирование DeepSeek API...\n');
|
||
print('=' * 60);
|
||
|
||
// Тест 1: Проверка API ключа (простой запрос)
|
||
print('\n📝 Тест 1: Проверка API ключа');
|
||
print('-' * 60);
|
||
await testApiKey(apiKey, baseUrl);
|
||
|
||
// Тест 2: Генерация подзадач
|
||
print('\n📋 Тест 2: Генерация подзадач');
|
||
print('-' * 60);
|
||
await testGenerateSubtasks(apiKey, baseUrl);
|
||
|
||
// Тест 3: Приоритизация задачи
|
||
print('\n🎯 Тест 3: Приоритизация задачи');
|
||
print('-' * 60);
|
||
await testPrioritizeTask(apiKey, baseUrl);
|
||
|
||
// Тест 4: Генерация описания
|
||
print('\n✍️ Тест 4: Генерация описания задачи');
|
||
print('-' * 60);
|
||
await testGenerateDescription(apiKey, baseUrl);
|
||
|
||
// Тест 5: Генерация mind-карты
|
||
print('️ Тест 5: Генерация mind-карты');
|
||
print('-' * 60);
|
||
await testGenerateMindMap(apiKey, baseUrl);
|
||
|
||
// Тест 6: Умное планирование
|
||
print('\n📅 Тест 6: Умное планирование');
|
||
print('-' * 60);
|
||
await testSmartSchedule(apiKey, baseUrl);
|
||
|
||
print('\n${'=' * 60}');
|
||
print('✅ Тестирование завершено!');
|
||
print('=' * 60);
|
||
}
|
||
|
||
// Тест 1: Проверка API ключа
|
||
Future<void> testApiKey(String apiKey, String baseUrl) async {
|
||
try {
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'user',
|
||
'content': 'Привет! Скажи "API работает отлично!"',
|
||
},
|
||
],
|
||
'max_tokens': 50,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final message = data['choices'][0]['message']['content'];
|
||
print('✅ API ключ валиден!');
|
||
print('💬 Ответ: $message');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|
||
|
||
// Тест 2: Генерация подзадач
|
||
Future<void> testGenerateSubtasks(String apiKey, String baseUrl) async {
|
||
try {
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'system',
|
||
'content': 'You are a task planning assistant. Break down tasks into logical subtasks. Return ONLY a JSON array.',
|
||
},
|
||
{
|
||
'role': 'user',
|
||
'content': 'Break down this task into 3-7 subtasks:\n\nTitle: Создать CRM систему\nDescription: Разработка CRM для управления задачами команды с AI планированием\n\nReturn ONLY a JSON array with format: [{"title": "...", "estimatedHours": 0, "description": "..."}]',
|
||
},
|
||
],
|
||
'temperature': 0.7,
|
||
'max_tokens': 2000,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final content = data['choices'][0]['message']['content'];
|
||
|
||
print('✅ Подзадачи сгенерированы!');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
print('\n📝 Результат:');
|
||
|
||
// Пытаемся распарсить JSON
|
||
final jsonMatch = RegExp(r'\[.*\]', dotAll: true).firstMatch(content);
|
||
if (jsonMatch != null) {
|
||
final List<dynamic> subtasks = jsonDecode(jsonMatch.group(0)!);
|
||
for (int i = 0; i < subtasks.length; i++) {
|
||
final task = subtasks[i];
|
||
print('\n${i + 1}. ${task['title']}');
|
||
print(' ⏱️ Часы: ${task['estimatedHours']}');
|
||
print(' 📄 ${task['description']}');
|
||
}
|
||
} else {
|
||
print(content);
|
||
}
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|
||
|
||
// Тест 3: Приоритизация задачи
|
||
Future<void> testPrioritizeTask(String apiKey, String baseUrl) async {
|
||
try {
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'system',
|
||
'content': 'You are a task prioritization assistant. Determine task priority: low, medium, high, or urgent. Reply with ONE word only.',
|
||
},
|
||
{
|
||
'role': 'user',
|
||
'content': 'What priority should this task have?\n\nTitle: Срочный баг - пользователи не могут войти\nDescription: Критическая ошибка авторизации, все пользователи заблокированы\nDue: 2026-04-09T12:00:00\n\nReply with ONE word: low, medium, high, or urgent',
|
||
},
|
||
],
|
||
'temperature': 0.3,
|
||
'max_tokens': 10,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final priority = data['choices'][0]['message']['content'].trim().toLowerCase();
|
||
|
||
print('✅ Приоритизация выполнена!');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
print('🎯 Приоритет: ${priority.toUpperCase()}');
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|
||
|
||
// Тест 4: Генерация описания
|
||
Future<void> testGenerateDescription(String apiKey, String baseUrl) async {
|
||
try {
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'system',
|
||
'content': 'You are a task description writer. Write clear, concise task descriptions in Russian. Keep it under 100 words.',
|
||
},
|
||
{
|
||
'role': 'user',
|
||
'content': 'Write a brief description for this task:\n\nTitle: Интеграция с Google Calendar\nContext: Синхронизация событий между CRM и Google Calendar\n\nWrite in Russian.',
|
||
},
|
||
],
|
||
'temperature': 0.5,
|
||
'max_tokens': 500,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final description = data['choices'][0]['message']['content'];
|
||
|
||
print('✅ Описание сгенерировано!');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
print('\n📝 Описание:\n$description');
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|
||
|
||
// Тест 5: Генерация mind-карты
|
||
Future<void> testGenerateMindMap(String apiKey, String baseUrl) async {
|
||
try {
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'system',
|
||
'content': 'You are a project structure assistant. Create a mind-map structure for projects. Return ONLY a JSON array of nodes.',
|
||
},
|
||
{
|
||
'role': 'user',
|
||
'content': '''Create a mind-map structure for this project:
|
||
|
||
Project: CRM App
|
||
Description: Мобильное CRM приложение с AI планированием, mind-картами и интеграцией с календарем
|
||
|
||
Return JSON array of nodes with format:
|
||
[{"level": 0, "title": "Project Name", "parentId": null}, {"level": 1, "title": "Phase 1", "parentId": 0}, ...]''',
|
||
},
|
||
],
|
||
'temperature': 0.7,
|
||
'max_tokens': 3000,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final content = data['choices'][0]['message']['content'];
|
||
|
||
print('✅ Mind-карта сгенерирована!');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
|
||
// Пытаемся распарсить JSON
|
||
final jsonMatch = RegExp(r'\[.*\]', dotAll: true).firstMatch(content);
|
||
if (jsonMatch != null) {
|
||
final List<dynamic> nodes = jsonDecode(jsonMatch.group(0)!);
|
||
print('\n🗺️ Структура mind-карты:');
|
||
for (final node in nodes) {
|
||
final indent = ' ' * (node['level'] as int);
|
||
print('$indent${node['level'] == 0 ? '📌' : '└'} ${node['title']}');
|
||
}
|
||
} else {
|
||
print('\n📝 Результат:\n$content');
|
||
}
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|
||
|
||
// Тест 6: Умное планирование
|
||
Future<void> testSmartSchedule(String apiKey, String baseUrl) async {
|
||
try {
|
||
final tasks = [
|
||
{'title': 'Анализ требований', 'estimatedHours': 4, 'priority': 'high'},
|
||
{'title': 'Проектирование', 'estimatedHours': 6, 'priority': 'high'},
|
||
{'title': 'Frontend разработка', 'estimatedHours': 12, 'priority': 'medium'},
|
||
{'title': 'Backend разработка', 'estimatedHours': 10, 'priority': 'medium'},
|
||
{'title': 'Тестирование', 'estimatedHours': 5, 'priority': 'high'},
|
||
];
|
||
|
||
final response = await http.post(
|
||
Uri.parse('$baseUrl/v1/chat/completions'),
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $apiKey',
|
||
},
|
||
body: jsonEncode({
|
||
'model': 'deepseek-chat',
|
||
'messages': [
|
||
{
|
||
'role': 'system',
|
||
'content': 'You are a smart scheduling assistant. Distribute tasks across available days optimally. Return ONLY a JSON array.',
|
||
},
|
||
{
|
||
'role': 'user',
|
||
'content': '''Schedule these tasks optimally:
|
||
${jsonEncode(tasks)}
|
||
|
||
Available hours per day: 6
|
||
Start date: 2026-04-09
|
||
End date: 2026-04-16
|
||
|
||
Return JSON array: [{"taskId": index, "taskName": "name", "date": "YYYY-MM-DD", "hours": 0}]''',
|
||
},
|
||
],
|
||
'temperature': 0.5,
|
||
'max_tokens': 3000,
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
final data = jsonDecode(response.body);
|
||
final content = data['choices'][0]['message']['content'];
|
||
|
||
print('✅ Планирование выполнено!');
|
||
print('📊 Использовано токенов: ${data['usage']['total_tokens']}');
|
||
|
||
// Пытаемся распарсить JSON
|
||
final jsonMatch = RegExp(r'\[.*\]', dotAll: true).firstMatch(content);
|
||
if (jsonMatch != null) {
|
||
final List<dynamic> schedule = jsonDecode(jsonMatch.group(0)!);
|
||
print('\n📅 Расписание:');
|
||
for (final item in schedule) {
|
||
print(' 📆 ${item['date']}: ${item['taskName'] ?? item['taskId']} (${item['hours']}ч)');
|
||
}
|
||
} else {
|
||
print('\n📝 Результат:\n$content');
|
||
}
|
||
} else {
|
||
print('❌ Ошибка: ${response.statusCode}');
|
||
print('📄 Ответ: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('❌ Исключение: $e');
|
||
}
|
||
}
|