forked from morrning/hesabixCore
progress in ai in person module
This commit is contained in:
parent
fc6f286e0e
commit
3b617f9971
|
@ -176,7 +176,8 @@ class wizardController extends AbstractController
|
|||
'response' => $responseContent,
|
||||
'conversationId' => $conversation->getId(),
|
||||
'model' => $result['model'] ?? null,
|
||||
'usage' => $result['usage'] ?? null
|
||||
'usage' => $result['usage'] ?? null,
|
||||
'debug_info' => $result['debug_info'] ?? null
|
||||
];
|
||||
|
||||
// محاسبه هزینه در صورت وجود اطلاعات usage
|
||||
|
@ -212,14 +213,21 @@ class wizardController extends AbstractController
|
|||
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'] ?? 'خطای نامشخص در سرویس هوش مصنوعی'
|
||||
'error' => $result['error'] ?? 'خطای نامشخص در سرویس هوش مصنوعی',
|
||||
'debug_info' => $result['debug_info'] ?? null
|
||||
]);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در پردازش درخواست: ' . $e->getMessage()
|
||||
'error' => 'خطا در پردازش درخواست: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'tool_commands' => [],
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@ -557,4 +565,377 @@ class wizardController extends AbstractController
|
|||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/execute-command', name: 'wizard_execute_command', methods: ['POST'])]
|
||||
public function wizard_execute_command(
|
||||
Request $request,
|
||||
Access $access,
|
||||
EntityManagerInterface $entityManager,
|
||||
Log $log
|
||||
): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید'
|
||||
]);
|
||||
}
|
||||
|
||||
$params = json_decode($request->getContent(), true) ?? [];
|
||||
|
||||
if (!isset($params['tool']) || !isset($params['params'])) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'ابزار و پارامترها الزامی هستند'
|
||||
]);
|
||||
}
|
||||
|
||||
$tool = $params['tool'];
|
||||
$commandParams = $params['params'];
|
||||
$business = $acc['bid'];
|
||||
|
||||
// اجرای دستور
|
||||
$result = null;
|
||||
switch ($tool) {
|
||||
case 'add_person':
|
||||
$result = $this->aiService->getPersonManagementService()->addPerson($commandParams, $business, $acc['user']);
|
||||
break;
|
||||
case 'edit_person':
|
||||
$result = $this->aiService->getPersonManagementService()->editPerson($commandParams, $business, $acc['user']);
|
||||
break;
|
||||
case 'delete_person':
|
||||
$result = $this->aiService->getPersonManagementService()->deletePerson($commandParams, $business, $acc['user']);
|
||||
break;
|
||||
case 'show_person':
|
||||
$result = $this->aiService->getPersonManagementService()->showPerson($commandParams, $business, $acc['user']);
|
||||
break;
|
||||
case 'search_persons':
|
||||
$result = $this->aiService->getPersonManagementService()->searchPersons($commandParams, $business);
|
||||
break;
|
||||
default:
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => "ابزار '{$tool}' شناخته نشد"
|
||||
]);
|
||||
}
|
||||
|
||||
if ($result && $result['success']) {
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => $result['message'] ?? 'عملیات با موفقیت انجام شد',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'دستور اجرا شد',
|
||||
'tool_commands' => [
|
||||
[
|
||||
'tool' => $tool,
|
||||
'params' => $commandParams
|
||||
]
|
||||
],
|
||||
'has_commands' => true,
|
||||
'execution_result' => $result
|
||||
]
|
||||
]);
|
||||
} else {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => $result['error'] ?? 'خطا در اجرای دستور',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطا در اجرای دستور',
|
||||
'tool_commands' => [
|
||||
[
|
||||
'tool' => $tool,
|
||||
'params' => $commandParams
|
||||
]
|
||||
],
|
||||
'has_commands' => true,
|
||||
'execution_result' => $result
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در اجرای دستور: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'tool_commands' => [],
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/test-debug-info', name: 'wizard_test_debug_info', methods: ['POST'])]
|
||||
public function wizard_test_debug_info(Access $access): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطای دسترسی',
|
||||
'tool_commands' => [],
|
||||
'has_commands' => false,
|
||||
'error_details' => 'No AI access'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => 'تست Debug Info با موفقیت انجام شد',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'این یک تست برای Debug Info است',
|
||||
'tool_commands' => [
|
||||
[
|
||||
'tool' => 'test_tool',
|
||||
'params' => ['test_param' => 'test_value']
|
||||
]
|
||||
],
|
||||
'has_commands' => true,
|
||||
'test_data' => 'این داده تست است'
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در تست Debug Info: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'tool_commands' => [],
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/test-interactive', name: 'wizard_test_interactive', methods: ['POST'])]
|
||||
public function wizard_test_interactive(Access $access): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطای دسترسی',
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => 'No AI access'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// تست سیستم تعاملی
|
||||
$testMessage = "تلفن 09123456789 را برای محسن اضافه کن";
|
||||
$business = $acc['bid'];
|
||||
|
||||
$result = $this->aiService->sendRequest($testMessage, $business, $acc['user']);
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => $result['response'] ?? 'تست سیستم تعاملی',
|
||||
'debug_info' => $result['debug_info'] ?? [
|
||||
'ai_response' => 'تست سیستم تعاملی',
|
||||
'action_type' => 'test',
|
||||
'has_commands' => false
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در تست سیستم تعاملی: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/test-interactive-system', name: 'wizard_test_interactive_system', methods: ['POST'])]
|
||||
public function wizard_test_interactive_system(Access $access): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطای دسترسی',
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => 'No AI access'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// تست سیستم تعاملی
|
||||
$testMessage = "تلفن 09123456789 را برای محسن اضافه کن";
|
||||
$business = $acc['bid'];
|
||||
|
||||
$result = $this->aiService->sendRequest($testMessage, $business, $acc['user']);
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => $result['response'] ?? 'تست سیستم تعاملی',
|
||||
'debug_info' => $result['debug_info'] ?? [
|
||||
'ai_response' => 'تست سیستم تعاملی',
|
||||
'action_type' => 'test',
|
||||
'has_commands' => false
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در تست سیستم تعاملی: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/test-continuous-operation', name: 'wizard_test_continuous_operation', methods: ['POST'])]
|
||||
public function wizard_test_continuous_operation(Access $access): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطای دسترسی',
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => 'No AI access'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// تست عملیات پیوسته
|
||||
$testMessage = "برای احمد موبایل 09123456789 تنظیم کن";
|
||||
$business = $acc['bid'];
|
||||
|
||||
$result = $this->aiService->sendRequest($testMessage, $business, $acc['user']);
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => $result['response'] ?? 'تست عملیات پیوسته',
|
||||
'debug_info' => $result['debug_info'] ?? [
|
||||
'ai_response' => 'تست عملیات پیوسته',
|
||||
'action_type' => 'test',
|
||||
'has_commands' => false
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در تست عملیات پیوسته: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
#[Route('/api/wizard/test-smart-operation', name: 'wizard_test_smart_operation', methods: ['POST'])]
|
||||
public function wizard_test_smart_operation(Access $access): JsonResponse
|
||||
{
|
||||
try {
|
||||
$acc = $access->hasRole('join');
|
||||
if (!$acc) {
|
||||
throw $this->createAccessDeniedException();
|
||||
}
|
||||
|
||||
// بررسی دسترسی هوش مصنوعی
|
||||
if (!$acc['ai']) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'شما دسترسی استفاده از هوش مصنوعی را ندارید',
|
||||
'debug_info' => [
|
||||
'ai_response' => 'خطای دسترسی',
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => 'No AI access'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
// تست عملیات هوشمند
|
||||
$testMessage = "تلفن 09123456789 را برای محسن اضافه کن";
|
||||
$business = $acc['bid'];
|
||||
|
||||
$result = $this->aiService->sendRequest($testMessage, $business, $acc['user']);
|
||||
|
||||
return $this->json([
|
||||
'success' => true,
|
||||
'response' => $result['response'] ?? 'تست عملیات هوشمند',
|
||||
'debug_info' => $result['debug_info'] ?? [
|
||||
'ai_response' => 'تست عملیات هوشمند',
|
||||
'action_type' => 'test',
|
||||
'has_commands' => false
|
||||
]
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'error' => 'خطا در تست عملیات هوشمند: ' . $e->getMessage(),
|
||||
'debug_info' => [
|
||||
'ai_response' => null,
|
||||
'action_type' => 'error',
|
||||
'has_commands' => false,
|
||||
'error_details' => $e->getMessage()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,10 @@ class AIService
|
|||
// پردازش پاسخ هوش مصنوعی برای تشخیص دستورات ابزار
|
||||
$processedResponse = $this->processAIResponse($aiResponse, $business, $user);
|
||||
|
||||
// اضافه کردن debug logging
|
||||
error_log('AIService Debug - AI Response: ' . $aiResponse);
|
||||
error_log('AIService Debug - Processed Response: ' . json_encode($processedResponse));
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'response' => $processedResponse['response'],
|
||||
|
@ -82,7 +86,8 @@ class AIService
|
|||
'service' => $service,
|
||||
'model' => $this->getAIModel(),
|
||||
'requires_action' => $processedResponse['requires_action'] ?? false,
|
||||
'action_data' => $processedResponse['action_data'] ?? null
|
||||
'action_data' => $processedResponse['action_data'] ?? null,
|
||||
'debug_info' => $processedResponse['debug_info'] ?? null
|
||||
];
|
||||
} else {
|
||||
// اگر کلید data وجود ندارد، احتمالاً پاسخ از ابزار است
|
||||
|
@ -143,62 +148,766 @@ class AIService
|
|||
*/
|
||||
private function getSystemPrompt(): string
|
||||
{
|
||||
return "شما یک دستیار هوشمند برای سیستم حسابداری حسابیکس هستید. شما دسترسی به ابزارهای زیر دارید:
|
||||
|
||||
🔧 ابزارهای موجود:
|
||||
|
||||
1. **مدیریت اشخاص** (person_management):
|
||||
- افزودن شخص جدید: add_person{name:نام مستعار}
|
||||
- حذف شخص: delete_person{name:نام مستعار}
|
||||
- ویرایش شخص: edit_person{name:نام مستعار, phone:موبایل, address:آدرس, email:ایمیل}
|
||||
- نمایش مشخصات: show_person{name:نام مستعار}
|
||||
- جستجوی اشخاص: search_persons{search:متن جستجو, limit:تعداد نتایج}
|
||||
|
||||
📋 قوانین استفاده:
|
||||
- اگر کاربر درخواست عملیات مدیریت اشخاص دارد، از دستورات بالا استفاده کنید
|
||||
- نام شخص = نام مستعار (nikename) که در دیتابیس فیلد الزامی است
|
||||
- نام مستعار معمولاً همان نامی است که کاربران استفاده میکنند
|
||||
- برای عملیات پیچیده، اطلاعات را جمعآوری کنید
|
||||
- همیشه پاسخ فارسی و واضح ارائه دهید
|
||||
- حتماً دستور ابزار را در پاسخ خود قرار دهید
|
||||
|
||||
🔄 حفظ context:
|
||||
- همیشه تاریخچه گفتگو را در نظر بگیرید
|
||||
- اگر کاربر به سوال قبلی اشاره میکند، آن را در نظر بگیرید
|
||||
- اگر نام شخص در سوال قبلی ذکر شده، از آن استفاده کنید
|
||||
- برای سوالات کوتاه، به context قبلی مراجعه کنید
|
||||
|
||||
💡 مثالهای استفاده:
|
||||
- 'علی رو حذف کن' → ابتدا بگویید: 'برای حذف شخص علی، از دستور delete_person{name:علی} استفاده میکنم.'
|
||||
- 'شخص جدید با نام احمد اضافه کن' → ابتدا بگویید: 'برای افزودن شخص جدید، از دستور add_person{name:احمد} استفاده میکنم.'
|
||||
- 'مشخصات محسن رو نشون بده' → ابتدا بگویید: 'برای نمایش مشخصات محسن، از دستور show_person{name:محسن} استفاده میکنم.'
|
||||
- 'اطلاعات رضا کمری رو بده' → ابتدا بگویید: 'برای نمایش مشخصات رضا کمری، از دستور show_person{name:رضا کمری} استفاده میکنم.'
|
||||
|
||||
💬 مثال حفظ context:
|
||||
- کاربر: 'اطلاعات رضا رو بهم بده'
|
||||
- دستیار: 'کدام رضا؟ لطفاً نام کامل یا نام مستعار را مشخص کنید.'
|
||||
- کاربر: 'کمری'
|
||||
- دستیار: 'برای نمایش مشخصات رضا کمری، از دستور show_person{name:رضا کمری} استفاده میکنم.'
|
||||
|
||||
⚠️ نکات مهم:
|
||||
- نام شخص = نام مستعار (nikename) در دیتابیس
|
||||
- حتماً دستور ابزار را در پاسخ خود قرار دهید
|
||||
- فقط از ابزارهایی که معرفی شدهاند استفاده کنید
|
||||
- اگر ابزار مناسب وجود ندارد، به کاربر بگویید
|
||||
- برای عملیات پیچیده، مرحله به مرحله پیش بروید
|
||||
- همیشه context گفتگو را حفظ کنید
|
||||
|
||||
لطفاً درخواست کاربر را بررسی کرده و در صورت نیاز از ابزارهای مناسب استفاده کنید. حتماً دستور ابزار را در پاسخ خود قرار دهید و context گفتگو را حفظ کنید.";
|
||||
return "شما یک دستیار هوشمند برای سیستم حسابداری حسابیکس هستید.\n\n🔧 ابزارهای موجود:\n\n1. **مدیریت اشخاص**:\n - افزودن شخص جدید: add_person{name:نام مستعار, full_name:نام کامل}\n - حذف شخص: delete_person{name:نام مستعار}\n - ویرایش شخص: edit_person{name:نام مستعار, mobile:موبایل, address:آدرس, email:ایمیل}\n - نمایش مشخصات: show_person{name:نام مستعار}\n - جستجوی اشخاص: search_persons{search:متن جستجو, limit:تعداد نتایج}\n\n📋 قوانین مهم:\n- حتماً از دستورات بالا استفاده کنید\n- نام شخص = نام مستعار (nikename) - فیلد الزامی\n- نام کامل (full_name) = نام و نام خانوادگی - فیلد اختیاری\n\n🔄 سیستم تعاملی چندمرحلهای:\nبرای عملیات پیچیده که نیاز به چند مرحله دارند، از ساختار JSON استفاده کنید:\n\n```json\n{
|
||||
\"action\": \"tool_command\",
|
||||
\"tool\": \"نام_ابزار\",
|
||||
\"params\": {
|
||||
\"param1\": \"value1\",
|
||||
\"param2\": \"value2\"
|
||||
},
|
||||
\"user_message\": \"پیام نمایشی برای کاربر\",
|
||||
\"debug_info\": \"اطلاعات دیباگ\",
|
||||
\"requires_followup\": true,
|
||||
\"next_step\": \"توضیح مرحله بعدی\"
|
||||
}
|
||||
```\n\n🔄 سیستم عملیات پیوسته تا حصول نتیجه:\nبرای عملیاتهایی که ممکن است نیاز به چندین تلاش داشته باشند، از متغیر `operation_complete` استفاده کنید:\n\n```json\n{
|
||||
\"action\": \"continuous_operation\",
|
||||
\"operation_type\": \"نوع_عملیات\",
|
||||
\"current_step\": \"مرحله_فعلی\",
|
||||
\"steps\": [
|
||||
{
|
||||
\"tool\": \"search_persons\",
|
||||
\"params\": {\"search\": \"محسن\"},
|
||||
\"purpose\": \"جستجوی شخص محسن\"
|
||||
}
|
||||
],
|
||||
\"user_message\": \"در حال جستجوی شخص محسن...\",
|
||||
\"debug_info\": \"عملیات پیوسته برای یافتن و ویرایش محسن\",
|
||||
\"operation_complete\": false,
|
||||
\"next_action\": \"اگر محسن پیدا نشد، شخص جدید بساز\",
|
||||
\"max_attempts\": 3
|
||||
}
|
||||
```\n\n🔄 سیستم عملیات هوشمند چندمرحلهای (جدید):\nبرای عملیاتهایی که نیاز به تصمیمگیری هوشمند دارند، از ساختار زیر استفاده کنید:\n\n```json\n{
|
||||
\"action\": \"smart_operation\",
|
||||
\"operation_type\": \"add_phone_to_person\",
|
||||
\"target_person\": \"محسن\",
|
||||
\"target_phone\": \"09123456789\",
|
||||
\"steps\": [
|
||||
{
|
||||
\"tool\": \"search_persons\",
|
||||
\"params\": {\"search\": \"محسن\"},
|
||||
\"purpose\": \"جستجوی شخص محسن\",
|
||||
\"on_success\": \"edit_person\",
|
||||
\"on_failure\": \"add_person\"
|
||||
}
|
||||
],
|
||||
\"user_message\": \"در حال جستجوی شخص محسن...\",
|
||||
\"debug_info\": \"عملیات هوشمند برای افزودن تلفن\",
|
||||
\"operation_complete\": false,
|
||||
\"next_action\": \"بر اساس نتیجه جستجو، شخص را ویرایش یا اضافه کن\"
|
||||
}
|
||||
```\n\n📝 انواع پاسخها:\n\n1. **پاسخ مستقیم** (برای عملیات ساده):\n```json\n{
|
||||
\"action\": \"direct_response\",
|
||||
\"user_message\": \"پیام نمایشی برای کاربر\",
|
||||
\"debug_info\": \"اطلاعات دیباگ\"
|
||||
}
|
||||
```\n\n2. **دستور ابزار** (برای عملیات تک مرحلهای):\n```json\n{
|
||||
\"action\": \"tool_command\",
|
||||
\"tool\": \"edit_person\",
|
||||
\"params\": {
|
||||
\"name\": \"محسن\",
|
||||
\"mobile\": \"09123456789\"
|
||||
},
|
||||
\"user_message\": \"در حال ویرایش موبایل محسن...\",
|
||||
\"debug_info\": \"اجرای دستور edit_person\"
|
||||
}
|
||||
```\n\n3. **عملیات چندمرحلهای** (برای عملیات پیچیده):\n```json\n{
|
||||
\"action\": \"multi_step\",
|
||||
\"steps\": [
|
||||
{
|
||||
\"tool\": \"search_persons\",
|
||||
\"params\": {\"search\": \"محسن\"},
|
||||
\"purpose\": \"جستجوی شخص محسن\"
|
||||
},
|
||||
{
|
||||
\"tool\": \"edit_person\",
|
||||
\"params\": {\"name\": \"محسن\", \"mobile\": \"09123456789\"},
|
||||
\"purpose\": \"ویرایش موبایل\"
|
||||
}
|
||||
],
|
||||
\"user_message\": \"در حال جستجو و ویرایش اطلاعات محسن...\",
|
||||
\"debug_info\": \"عملیات چندمرحلهای\",
|
||||
\"requires_followup\": true
|
||||
}
|
||||
```\n\n4. **عملیات هوشمند چندمرحلهای** (جدید):\n```json\n{
|
||||
\"action\": \"smart_operation\",
|
||||
\"operation_type\": \"add_phone_to_person\",
|
||||
\"target_person\": \"محسن\",
|
||||
\"target_phone\": \"09123456789\",
|
||||
\"steps\": [
|
||||
{
|
||||
\"tool\": \"search_persons\",
|
||||
\"params\": {\"search\": \"محسن\"},
|
||||
\"purpose\": \"جستجوی شخص محسن\",
|
||||
\"on_success\": \"edit_person\",
|
||||
\"on_failure\": \"add_person\"
|
||||
}
|
||||
],
|
||||
\"user_message\": \"در حال جستجوی شخص محسن...\",
|
||||
\"debug_info\": \"عملیات هوشمند برای افزودن تلفن\",
|
||||
\"operation_complete\": false,
|
||||
\"next_action\": \"بر اساس نتیجه جستجو، شخص را ویرایش یا اضافه کن\"
|
||||
}
|
||||
```\n\n5. **نتیجه نهایی** (وقتی عملیات کامل شد):\n```json\n{
|
||||
\"action\": \"operation_complete\",
|
||||
\"operation_type\": \"add_phone_to_person\",
|
||||
\"final_result\": \"عملیات با موفقیت انجام شد\",
|
||||
\"user_message\": \"موبایل 09123456789 برای محسن محمودی با موفقیت اضافه شد\",
|
||||
\"debug_info\": \"عملیات پیوسته کامل شد\",
|
||||
\"operation_complete\": true,
|
||||
\"total_steps\": 2,
|
||||
\"final_data\": {
|
||||
\"person_id\": 139,
|
||||
\"person_name\": \"محسن محمودی\",
|
||||
\"new_mobile\": \"09123456789\"
|
||||
}
|
||||
}
|
||||
```\n\n💡 مثالهای استفاده:\n\n**مثال 1 - عملیات ساده:**\n- 'علی رو حذف کن' → دستور مستقیم delete_person\n\n**مثال 2 - عملیات با جستجو:**\n- 'تلفن 09123456789 را برای محسن اضافه کن' → ابتدا جستجو، سپس ویرایش\n\n**مثال 3 - عملیات هوشمند:**\n- 'شخصی با نام محسن پیدا کن و موبایلش رو 09123456789 کن' → جستجو + اگر پیدا شد ویرایش + اگر پیدا نشد بساز\n\n**مثال 4 - عملیات پیچیده:**\n- 'برای احمد موبایل 09123456789 تنظیم کن' → جستجو + اگر پیدا نشد بساز + ویرایش موبایل\n\n**مثال 5 - نمایش نتایج جستجو:**\n- '5 نفر اخیر را نشان بده' → جستجو + نمایش مستقیم نتایج بدون followup\n\n⚠️ نکات مهم:\n- حتماً از ساختار JSON استفاده کنید\n- برای عملیات پیچیده، ابتدا جستجو کنید\n- اگر شخصی پیدا نشد، شخص جدید بسازید\n- پیامهای کاربر را واضح و مفید بنویسید\n- اطلاعات دیباگ را کامل ارائه دهید\n- برای عملیاتهایی که فقط نیاز به نمایش نتایج دارند، requires_followup را false کنید\n- برای عملیات پیوسته، operation_complete را false نگه دارید تا به نتیجه برسید\n- وقتی عملیات کامل شد، operation_complete را true کنید و نتیجه نهایی را ارائه دهید\n- برای عملیات هوشمند، از on_success و on_failure استفاده کنید تا مرحله بعدی مشخص شود\n- برای جستجو و نمایش نتایج، مستقیماً نتایج را در user_message قرار دهید و requires_followup را false کنید\n\n🔄 منطق عملیات هوشمند:\n1. ابتدا جستجو کنید\n2. اگر پیدا شد، عملیات مورد نظر را انجام دهید\n3. اگر پیدا نشد، شخص جدید بسازید\n4. سپس عملیات مورد نظر را انجام دهید\n5. در نهایت operation_complete را true کنید\n\n🔄 منطق عملیات پیوسته:\n1. ابتدا جستجو کنید\n2. اگر پیدا شد، عملیات مورد نظر را انجام دهید\n3. اگر پیدا نشد، شخص جدید بسازید\n4. سپس عملیات مورد نظر را انجام دهید\n5. در نهایت operation_complete را true کنید\n\n🔄 منطق نمایش نتایج:\n1. جستجو را انجام دهید\n2. نتایج را مستقیماً در user_message قرار دهید\n3. requires_followup را false کنید\n4. اطلاعات کامل را در debug_info قرار دهید\n\n🔄 منطق پاسخدهی عمومی:\n1. سوال را بررسی کنید\n2. اگر سوال عمومی است، پاسخ آموزشی ارائه دهید\n3. از direct_response استفاده کنید\n4. اطلاعات مفید و کامل ارائه دهید\n\nلطفاً درخواست کاربر را بررسی کرده و پاسخ مناسب را با ساختار JSON ارائه دهید.";
|
||||
}
|
||||
|
||||
/**
|
||||
* پردازش پاسخ هوش مصنوعی و تشخیص دستورات ابزار
|
||||
*/
|
||||
private function processAIResponse(string $aiResponse, ?Business $business, $user): array
|
||||
{
|
||||
// ابتدا سعی کن JSON را از پاسخ استخراج کن
|
||||
$jsonResponse = $this->extractJSONFromResponse($aiResponse);
|
||||
|
||||
if ($jsonResponse) {
|
||||
return $this->processJSONResponse($jsonResponse, $aiResponse, $business, $user);
|
||||
}
|
||||
|
||||
// اگر JSON یافت نشد، از روش قدیمی استفاده کن
|
||||
return $this->processLegacyResponse($aiResponse, $business, $user);
|
||||
}
|
||||
|
||||
/**
|
||||
* استخراج JSON از پاسخ AI
|
||||
*/
|
||||
private function extractJSONFromResponse(string $aiResponse): ?array
|
||||
{
|
||||
// جستجوی JSON در پاسخ
|
||||
if (preg_match('/```json\s*(\{.*?\})\s*```/s', $aiResponse, $matches)) {
|
||||
$jsonString = $matches[1];
|
||||
} elseif (preg_match('/(\{.*\})/s', $aiResponse, $matches)) {
|
||||
$jsonString = $matches[1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$decoded = json_decode($jsonString, true);
|
||||
return $decoded ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* پردازش پاسخ JSON
|
||||
*/
|
||||
private function processJSONResponse(array $jsonResponse, string $originalResponse, ?Business $business, $user): array
|
||||
{
|
||||
$action = $jsonResponse['action'] ?? 'direct_response';
|
||||
|
||||
switch ($action) {
|
||||
case 'direct_response':
|
||||
return [
|
||||
'response' => $jsonResponse['user_message'] ?? $originalResponse,
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'direct_response',
|
||||
'has_commands' => false
|
||||
]
|
||||
];
|
||||
|
||||
case 'tool_command':
|
||||
return $this->executeSingleToolCommand($jsonResponse, $originalResponse, $business, $user);
|
||||
|
||||
case 'multi_step':
|
||||
return $this->executeMultiStepCommand($jsonResponse, $originalResponse, $business, $user);
|
||||
|
||||
case 'continuous_operation':
|
||||
return $this->executeContinuousOperation($jsonResponse, $originalResponse, $business, $user);
|
||||
|
||||
case 'smart_operation':
|
||||
return $this->executeSmartOperation($jsonResponse, $originalResponse, $business, $user);
|
||||
|
||||
case 'operation_complete':
|
||||
return [
|
||||
'response' => $jsonResponse['user_message'] ?? 'عملیات با موفقیت کامل شد',
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'operation_complete',
|
||||
'has_commands' => false,
|
||||
'final_result' => $jsonResponse['final_result'] ?? null,
|
||||
'final_data' => $jsonResponse['final_data'] ?? null
|
||||
]
|
||||
];
|
||||
|
||||
default:
|
||||
return [
|
||||
'response' => $jsonResponse['user_message'] ?? $originalResponse,
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'unknown',
|
||||
'has_commands' => false,
|
||||
'error' => 'نوع عملیات نامعتبر'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* اجرای دستور ابزار تک مرحلهای
|
||||
*/
|
||||
private function executeSingleToolCommand(array $jsonResponse, string $originalResponse, ?Business $business, $user): array
|
||||
{
|
||||
$tool = $jsonResponse['tool'] ?? '';
|
||||
$params = $jsonResponse['params'] ?? [];
|
||||
|
||||
if (empty($tool)) {
|
||||
return [
|
||||
'response' => $jsonResponse['user_message'] ?? 'خطا: ابزار مشخص نشده است',
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'tool_command',
|
||||
'has_commands' => false,
|
||||
'error' => 'ابزار مشخص نشده است'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$result = $this->executeToolCommand(['tool' => $tool, 'params' => $params], $business, $user);
|
||||
|
||||
$finalResponse = $jsonResponse['user_message'] ?? 'عملیات انجام شد';
|
||||
|
||||
// برای جستجو، نتایج را مستقیماً نمایش بده
|
||||
if ($tool === 'search_persons' && $result['success'] && isset($result['persons'])) {
|
||||
$persons = $result['persons'];
|
||||
$count = count($persons);
|
||||
|
||||
if ($count > 0) {
|
||||
$finalResponse .= "\n\n";
|
||||
if (isset($params['search']) && !empty($params['search'])) {
|
||||
$finalResponse .= "نتایج جستجو برای \"{$params['search']}\":\n";
|
||||
} else {
|
||||
$finalResponse .= "لیست {$count} نفر اخیر:\n";
|
||||
}
|
||||
|
||||
foreach ($persons as $index => $person) {
|
||||
$finalResponse .= "\n" . ($index + 1) . ". ";
|
||||
if (!empty($person['nikename'])) {
|
||||
$finalResponse .= $person['nikename'];
|
||||
} elseif (!empty($person['name'])) {
|
||||
$finalResponse .= $person['name'];
|
||||
} else {
|
||||
$finalResponse .= "شخص " . $person['code'];
|
||||
}
|
||||
|
||||
if (!empty($person['mobile'])) {
|
||||
$finalResponse .= " - موبایل: " . $person['mobile'];
|
||||
}
|
||||
|
||||
$finalResponse .= " (کد: " . $person['code'] . ")";
|
||||
}
|
||||
} else {
|
||||
$finalResponse .= "\n\nهیچ شخصی یافت نشد.";
|
||||
}
|
||||
|
||||
// برای جستجو، followup را غیرفعال کن
|
||||
$requiresFollowup = false;
|
||||
} elseif ($tool === 'show_person' && $result['success'] && isset($result['person'])) {
|
||||
// برای نمایش اطلاعات شخص، نتایج را مستقیماً نمایش بده
|
||||
$person = $result['person'];
|
||||
|
||||
$finalResponse .= "\n\n";
|
||||
$finalResponse .= "📋 اطلاعات شخص:\n";
|
||||
$finalResponse .= "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n";
|
||||
|
||||
// نمایش اطلاعات اصلی
|
||||
if (isset($person['نام مستعار']) && !empty($person['نام مستعار'])) {
|
||||
$finalResponse .= "👤 نام مستعار: " . $person['نام مستعار'] . "\n";
|
||||
}
|
||||
if (isset($person['نام کامل']) && !empty($person['نام کامل'])) {
|
||||
$finalResponse .= "📝 نام کامل: " . $person['نام کامل'] . "\n";
|
||||
}
|
||||
if (isset($person['کد']) && !empty($person['کد'])) {
|
||||
$finalResponse .= "🔢 کد: " . $person['کد'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش اطلاعات تماس
|
||||
if (isset($person['موبایل']) && !empty($person['موبایل']) && $person['موبایل'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "📱 موبایل: " . $person['موبایل'] . "\n";
|
||||
}
|
||||
if (isset($person['تلفن']) && !empty($person['تلفن']) && $person['تلفن'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "☎️ تلفن: " . $person['تلفن'] . "\n";
|
||||
}
|
||||
if (isset($person['ایمیل']) && !empty($person['ایمیل']) && $person['ایمیل'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "📧 ایمیل: " . $person['ایمیل'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش اطلاعات آدرس
|
||||
if (isset($person['آدرس']) && !empty($person['آدرس']) && $person['آدرس'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "📍 آدرس: " . $person['آدرس'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش اطلاعات شرکت
|
||||
if (isset($person['شرکت']) && !empty($person['شرکت']) && $person['شرکت'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "🏢 شرکت: " . $person['شرکت'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش اطلاعات مالی
|
||||
if (isset($person['تراز حساب']) && !empty($person['تراز حساب'])) {
|
||||
$finalResponse .= "💰 تراز حساب: " . $person['تراز حساب'] . "\n";
|
||||
}
|
||||
if (isset($person['وضعیت حساب']) && !empty($person['وضعیت حساب'])) {
|
||||
$finalResponse .= "📊 وضعیت حساب: " . $person['وضعیت حساب'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش اطلاعات شناسایی
|
||||
if (isset($person['شناسه ملی']) && !empty($person['شناسه ملی']) && $person['شناسه ملی'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "🆔 شناسه ملی: " . $person['شناسه ملی'] . "\n";
|
||||
}
|
||||
if (isset($person['کد اقتصادی']) && !empty($person['کد اقتصادی']) && $person['کد اقتصادی'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "🏛️ کد اقتصادی: " . $person['کد اقتصادی'] . "\n";
|
||||
}
|
||||
|
||||
// نمایش انواع
|
||||
if (isset($person['انواع']) && !empty($person['انواع']) && $person['انواع'] !== 'تعیین نشده') {
|
||||
$finalResponse .= "🏷️ انواع: " . $person['انواع'] . "\n";
|
||||
}
|
||||
|
||||
$finalResponse .= "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━";
|
||||
|
||||
// برای نمایش اطلاعات شخص، followup را غیرفعال کن
|
||||
$requiresFollowup = false;
|
||||
} else {
|
||||
// برای سایر عملیات، از تنظیمات AI استفاده کن
|
||||
if ($result['success']) {
|
||||
$finalResponse .= "\n\n" . ($result['message'] ?? 'عملیات با موفقیت انجام شد');
|
||||
} else {
|
||||
$finalResponse .= "\n\nخطا: " . ($result['error'] ?? 'خطای نامشخص');
|
||||
}
|
||||
|
||||
$requiresFollowup = $jsonResponse['requires_followup'] ?? false;
|
||||
}
|
||||
|
||||
return [
|
||||
'response' => $finalResponse,
|
||||
'requires_action' => $requiresFollowup,
|
||||
'action_data' => $jsonResponse['next_step'] ?? null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'tool_command',
|
||||
'tool_commands' => [['tool' => $tool, 'params' => $params]],
|
||||
'has_commands' => true,
|
||||
'execution_result' => $result
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* اجرای دستور چندمرحلهای
|
||||
*/
|
||||
private function executeMultiStepCommand(array $jsonResponse, string $originalResponse, ?Business $business, $user): array
|
||||
{
|
||||
$steps = $jsonResponse['steps'] ?? [];
|
||||
$results = [];
|
||||
$allCommands = [];
|
||||
|
||||
foreach ($steps as $step) {
|
||||
$tool = $step['tool'] ?? '';
|
||||
$params = $step['params'] ?? [];
|
||||
|
||||
if (!empty($tool)) {
|
||||
$allCommands[] = ['tool' => $tool, 'params' => $params];
|
||||
$result = $this->executeToolCommand(['tool' => $tool, 'params' => $params], $business, $user);
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
$finalResponse = $jsonResponse['user_message'] ?? 'عملیات چندمرحلهای انجام شد';
|
||||
|
||||
// اضافه کردن نتایج به پاسخ
|
||||
foreach ($results as $index => $result) {
|
||||
if ($result['success']) {
|
||||
$finalResponse .= "\n\nمرحله " . ($index + 1) . ": " . ($result['message'] ?? 'موفق');
|
||||
} else {
|
||||
$finalResponse .= "\n\nمرحله " . ($index + 1) . ": خطا - " . ($result['error'] ?? 'خطای نامشخص');
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'response' => $finalResponse,
|
||||
'requires_action' => $jsonResponse['requires_followup'] ?? false,
|
||||
'action_data' => $jsonResponse['next_step'] ?? null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'multi_step',
|
||||
'tool_commands' => $allCommands,
|
||||
'has_commands' => true,
|
||||
'execution_results' => $results
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* اجرای عملیات پیوسته تا حصول نتیجه
|
||||
*/
|
||||
private function executeContinuousOperation(array $jsonResponse, string $originalResponse, ?Business $business, $user): array
|
||||
{
|
||||
$operationType = $jsonResponse['operation_type'] ?? '';
|
||||
$currentStep = $jsonResponse['current_step'] ?? 1;
|
||||
$steps = $jsonResponse['steps'] ?? [];
|
||||
$maxAttempts = $jsonResponse['max_attempts'] ?? 3;
|
||||
$attemptCount = $jsonResponse['attempt_count'] ?? 1;
|
||||
$operationComplete = $jsonResponse['operation_complete'] ?? false;
|
||||
|
||||
// اگر عملیات کامل شده، نتیجه نهایی را برگردان
|
||||
if ($operationComplete) {
|
||||
return [
|
||||
'response' => $jsonResponse['user_message'] ?? 'عملیات با موفقیت کامل شد',
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'operation_complete',
|
||||
'has_commands' => false,
|
||||
'final_result' => $jsonResponse['final_result'] ?? null,
|
||||
'final_data' => $jsonResponse['final_data'] ?? null
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// اگر تعداد تلاشها از حد مجاز بیشتر شد
|
||||
if ($attemptCount > $maxAttempts) {
|
||||
return [
|
||||
'response' => 'تعداد تلاشها از حد مجاز بیشتر شد. لطفاً درخواست خود را واضحتر بیان کنید.',
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'continuous_operation',
|
||||
'has_commands' => false,
|
||||
'error' => 'تعداد تلاشها از حد مجاز بیشتر شد',
|
||||
'attempt_count' => $attemptCount,
|
||||
'max_attempts' => $maxAttempts
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// اجرای مراحل فعلی
|
||||
$results = [];
|
||||
$allCommands = [];
|
||||
|
||||
foreach ($steps as $step) {
|
||||
$tool = $step['tool'] ?? '';
|
||||
$params = $step['params'] ?? [];
|
||||
|
||||
if (!empty($tool)) {
|
||||
$allCommands[] = ['tool' => $tool, 'params' => $params];
|
||||
$result = $this->executeToolCommand(['tool' => $tool, 'params' => $params], $business, $user);
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
// بررسی نتایج و تصمیمگیری برای مرحله بعدی
|
||||
$nextAction = $this->determineNextAction($operationType, $results, $jsonResponse);
|
||||
|
||||
$finalResponse = $jsonResponse['user_message'] ?? 'عملیات پیوسته در حال اجرا...';
|
||||
|
||||
// اضافه کردن نتایج به پاسخ
|
||||
foreach ($results as $index => $result) {
|
||||
if ($result['success']) {
|
||||
$finalResponse .= "\n\nمرحله " . ($index + 1) . ": " . ($result['message'] ?? 'موفق');
|
||||
} else {
|
||||
$finalResponse .= "\n\nمرحله " . ($index + 1) . ": خطا - " . ($result['error'] ?? 'خطای نامشخص');
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'response' => $finalResponse,
|
||||
'requires_action' => true,
|
||||
'action_data' => [
|
||||
'operation_type' => $operationType,
|
||||
'current_step' => $currentStep,
|
||||
'next_action' => $nextAction,
|
||||
'attempt_count' => $attemptCount,
|
||||
'max_attempts' => $maxAttempts,
|
||||
'results' => $results
|
||||
],
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'continuous_operation',
|
||||
'tool_commands' => $allCommands,
|
||||
'has_commands' => true,
|
||||
'execution_results' => $results,
|
||||
'operation_type' => $operationType,
|
||||
'current_step' => $currentStep,
|
||||
'attempt_count' => $attemptCount,
|
||||
'max_attempts' => $maxAttempts,
|
||||
'next_action' => $nextAction
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* اجرای عملیات هوشمند چندمرحلهای
|
||||
*/
|
||||
private function executeSmartOperation(array $jsonResponse, string $originalResponse, ?Business $business, $user): array
|
||||
{
|
||||
$operationType = $jsonResponse['operation_type'] ?? '';
|
||||
$targetPerson = $jsonResponse['target_person'] ?? '';
|
||||
$targetPhone = $jsonResponse['target_phone'] ?? '';
|
||||
$steps = $jsonResponse['steps'] ?? [];
|
||||
|
||||
// اجرای مرحله اول (معمولاً جستجو)
|
||||
$firstStep = $steps[0] ?? null;
|
||||
if (!$firstStep) {
|
||||
return [
|
||||
'response' => 'خطا: مرحله اول تعریف نشده است',
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation',
|
||||
'has_commands' => false,
|
||||
'error' => 'مرحله اول تعریف نشده'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
$tool = $firstStep['tool'] ?? '';
|
||||
$params = $firstStep['params'] ?? [];
|
||||
$onSuccess = $firstStep['on_success'] ?? '';
|
||||
$onFailure = $firstStep['on_failure'] ?? '';
|
||||
|
||||
// اجرای مرحله اول
|
||||
$result = $this->executeToolCommand(['tool' => $tool, 'params' => $params], $business, $user);
|
||||
|
||||
if ($result['success']) {
|
||||
// بررسی نتیجه جستجو
|
||||
if (isset($result['persons'])) {
|
||||
if (!empty($result['persons'])) {
|
||||
// شخص پیدا شد، عملیات on_success را انجام بده
|
||||
return $this->executeNextStep($onSuccess, $targetPerson, $targetPhone, $result, $business, $user, $originalResponse, $jsonResponse);
|
||||
} else {
|
||||
// شخص پیدا نشد، عملیات on_failure را انجام بده
|
||||
return $this->executeNextStep($onFailure, $targetPerson, $targetPhone, $result, $business, $user, $originalResponse, $jsonResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// اگر نتیجه ناموفق بود
|
||||
return [
|
||||
'response' => 'خطا در اجرای عملیات: ' . ($result['error'] ?? 'خطای نامشخص'),
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation',
|
||||
'has_commands' => true,
|
||||
'execution_result' => $result,
|
||||
'error' => 'خطا در اجرای مرحله اول'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* اجرای مرحله بعدی بر اساس نتیجه
|
||||
*/
|
||||
private function executeNextStep(string $action, string $targetPerson, string $targetPhone, array $searchResult, ?Business $business, $user, string $originalResponse, array $jsonResponse): array
|
||||
{
|
||||
switch ($action) {
|
||||
case 'edit_person':
|
||||
// ویرایش شخص موجود
|
||||
$person = $searchResult['persons'][0] ?? null;
|
||||
if ($person) {
|
||||
$editParams = [
|
||||
'name' => $person['nikename'],
|
||||
'mobile' => $targetPhone
|
||||
];
|
||||
|
||||
$editResult = $this->executeToolCommand(['tool' => 'edit_person', 'params' => $editParams], $business, $user);
|
||||
|
||||
if ($editResult['success']) {
|
||||
return [
|
||||
'response' => "موبایل {$targetPhone} برای {$targetPerson} با موفقیت تنظیم شد",
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation_complete',
|
||||
'has_commands' => true,
|
||||
'search_result' => $searchResult,
|
||||
'edit_result' => $editResult,
|
||||
'final_result' => 'عملیات ویرایش با موفقیت انجام شد'
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'response' => 'خطا در ویرایش موبایل: ' . ($editResult['error'] ?? 'خطای نامشخص'),
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation',
|
||||
'has_commands' => true,
|
||||
'search_result' => $searchResult,
|
||||
'edit_result' => $editResult,
|
||||
'error' => 'خطا در ویرایش'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'add_person':
|
||||
// افزودن شخص جدید
|
||||
$addParams = [
|
||||
'name' => $targetPerson,
|
||||
'mobile' => $targetPhone
|
||||
];
|
||||
|
||||
$addResult = $this->executeToolCommand(['tool' => 'add_person', 'params' => $addParams], $business, $user);
|
||||
|
||||
if ($addResult['success']) {
|
||||
return [
|
||||
'response' => "شخص جدید {$targetPerson} با موبایل {$targetPhone} با موفقیت ایجاد شد",
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation_complete',
|
||||
'has_commands' => true,
|
||||
'search_result' => $searchResult,
|
||||
'add_result' => $addResult,
|
||||
'final_result' => 'عملیات افزودن با موفقیت انجام شد'
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'response' => 'خطا در افزودن شخص: ' . ($addResult['error'] ?? 'خطای نامشخص'),
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation',
|
||||
'has_commands' => true,
|
||||
'search_result' => $searchResult,
|
||||
'add_result' => $addResult,
|
||||
'error' => 'خطا در افزودن'
|
||||
]
|
||||
];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return [
|
||||
'response' => 'عملیات نامشخص: ' . $action,
|
||||
'requires_action' => false,
|
||||
'action_data' => null,
|
||||
'debug_info' => [
|
||||
'ai_response' => $originalResponse,
|
||||
'json_response' => $jsonResponse,
|
||||
'action_type' => 'smart_operation',
|
||||
'has_commands' => false,
|
||||
'error' => 'عملیات نامشخص: ' . $action
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* تعیین مرحله بعدی بر اساس نتایج
|
||||
*/
|
||||
private function determineNextAction(string $operationType, array $results, array $jsonResponse): string
|
||||
{
|
||||
switch ($operationType) {
|
||||
case 'add_phone_to_person':
|
||||
// بررسی نتایج جستجو
|
||||
foreach ($results as $result) {
|
||||
if (isset($result['persons']) && empty($result['persons'])) {
|
||||
// شخص پیدا نشد، باید شخص جدید بسازیم
|
||||
return "شخص پیدا نشد. در حال ساخت شخص جدید...";
|
||||
} elseif (isset($result['persons']) && !empty($result['persons'])) {
|
||||
// شخص پیدا شد، موبایل را ویرایش کن
|
||||
return "شخص پیدا شد. در حال ویرایش موبایل...";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit_person_info':
|
||||
// بررسی نتایج جستجو
|
||||
foreach ($results as $result) {
|
||||
if (isset($result['persons']) && empty($result['persons'])) {
|
||||
return "شخص پیدا نشد. لطفاً نام صحیح را وارد کنید.";
|
||||
} elseif (isset($result['persons']) && !empty($result['persons'])) {
|
||||
return "شخص پیدا شد. در حال ویرایش اطلاعات...";
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'delete_person':
|
||||
// بررسی نتایج جستجو
|
||||
foreach ($results as $result) {
|
||||
if (isset($result['persons']) && empty($result['persons'])) {
|
||||
return "شخص پیدا نشد. لطفاً نام صحیح را وارد کنید.";
|
||||
} elseif (isset($result['persons']) && !empty($result['persons'])) {
|
||||
return "شخص پیدا شد. در حال حذف...";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $jsonResponse['next_action'] ?? "مرحله بعدی تعیین نشده";
|
||||
}
|
||||
|
||||
/**
|
||||
* پردازش پاسخ قدیمی (برای سازگاری)
|
||||
*/
|
||||
private function processLegacyResponse(string $aiResponse, ?Business $business, $user): array
|
||||
{
|
||||
// تشخیص دستورات ابزار در پاسخ
|
||||
$toolCommands = $this->extractToolCommands($aiResponse);
|
||||
|
||||
// اضافه کردن debug info
|
||||
$debugInfo = [
|
||||
'ai_response' => $aiResponse,
|
||||
'tool_commands' => $toolCommands,
|
||||
'has_commands' => !empty($toolCommands),
|
||||
'response_type' => 'legacy'
|
||||
];
|
||||
|
||||
// اگر دستور ابزاری یافت نشد، سعی کن دستورات را از متن استخراج کن
|
||||
if (empty($toolCommands)) {
|
||||
$extractedCommands = $this->extractCommandsFromText($aiResponse);
|
||||
if (!empty($extractedCommands)) {
|
||||
$toolCommands = $extractedCommands;
|
||||
$debugInfo['extracted_commands'] = $extractedCommands;
|
||||
$debugInfo['has_commands'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($toolCommands)) {
|
||||
// اجرای دستورات ابزار
|
||||
$results = [];
|
||||
|
@ -213,7 +922,8 @@ class AIService
|
|||
return [
|
||||
'response' => $finalResponse,
|
||||
'requires_action' => false,
|
||||
'action_data' => null
|
||||
'action_data' => null,
|
||||
'debug_info' => $debugInfo
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -221,7 +931,8 @@ class AIService
|
|||
return [
|
||||
'response' => $aiResponse,
|
||||
'requires_action' => false,
|
||||
'action_data' => null
|
||||
'action_data' => null,
|
||||
'debug_info' => $debugInfo
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -232,13 +943,13 @@ class AIService
|
|||
{
|
||||
$commands = [];
|
||||
|
||||
// الگوهای دستورات ابزار
|
||||
// الگوهای دستورات ابزار - ساده شده
|
||||
$patterns = [
|
||||
'add_person' => '/add_person\{name:([^}]+)\}/u',
|
||||
'add_person' => '/add_person\{([^}]+)\}/u',
|
||||
'delete_person' => '/delete_person\{name:([^}]+)\}/u',
|
||||
'edit_person' => '/edit_person\{name:([^}]+)(?:,([^}]+))*\}/u',
|
||||
'edit_person' => '/edit_person\{([^}]+)\}/u',
|
||||
'show_person' => '/show_person\{name:([^}]+)\}/u',
|
||||
'search_persons' => '/search_persons\{search:([^}]+)(?:,limit:([^}]+))*\}/u'
|
||||
'search_persons' => '/search_persons\{search:([^}]+)\}/u'
|
||||
];
|
||||
|
||||
foreach ($patterns as $tool => $pattern) {
|
||||
|
@ -256,6 +967,62 @@ class AIService
|
|||
return $commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* استخراج دستورات از متن پاسخ AI
|
||||
*/
|
||||
private function extractCommandsFromText(string $text): array
|
||||
{
|
||||
$commands = [];
|
||||
$text = mb_strtolower($text, 'UTF-8');
|
||||
|
||||
// الگوهای تشخیص دستورات برای فارسی
|
||||
$patterns = [
|
||||
'add_person' => [
|
||||
'/(?:افزودن|اضافه|ایجاد|ساخت)\s+(?:شخص|مشتری|کارمند)\s+(?:جدید\s+)?(?:با\s+نام\s+)?([^\s،]+)/u',
|
||||
'/(?:شخص|مشتری|کارمند)\s+(?:جدید\s+)?(?:با\s+نام\s+)?([^\s،]+)\s+(?:اضافه|افزودن|ایجاد|ساخت)/u',
|
||||
'/([^\s،]+)\s+(?:اضافه|افزودن|ایجاد|ساخت)/u',
|
||||
'/(?:برای|به)\s+([^\s،]+)\s+(?:اضافه|افزودن|ایجاد|ساخت)/u'
|
||||
],
|
||||
'edit_person' => [
|
||||
'/(?:ویرایش|تغییر|تنظیم)\s+(?:موبایل|شماره|تلفن)\s+(?:برای|به)\s+([^\s،]+)\s+(?:به\s+)?([0-9]+)/u',
|
||||
'/([^\s،]+)\s+(?:موبایل|شماره|تلفن)\s+(?:به\s+)?([0-9]+)/u',
|
||||
'/(?:موبایل|شماره|تلفن)\s+([0-9]+)\s+(?:را\s+)?(?:برای|به)\s+([^\s،]+)/u',
|
||||
'/(?:برای|به)\s+([^\s،]+)\s+(?:موبایل|شماره|تلفن)\s+([0-9]+)/u'
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($patterns as $tool => $toolPatterns) {
|
||||
foreach ($toolPatterns as $pattern) {
|
||||
if (preg_match($pattern, $text, $matches)) {
|
||||
if ($tool === 'add_person') {
|
||||
$commands[] = [
|
||||
'tool' => $tool,
|
||||
'params' => ['name' => $matches[1]]
|
||||
];
|
||||
} elseif ($tool === 'edit_person') {
|
||||
// تشخیص اینکه کدام پارامتر نام و کدام موبایل است
|
||||
if (preg_match('/^[0-9]+$/', $matches[1])) {
|
||||
// اگر اولین پارامتر عدد است، پس موبایل است
|
||||
$commands[] = [
|
||||
'tool' => $tool,
|
||||
'params' => ['name' => $matches[2], 'mobile' => $matches[1]]
|
||||
];
|
||||
} else {
|
||||
// اگر اولین پارامتر عدد نیست، پس نام است
|
||||
$commands[] = [
|
||||
'tool' => $tool,
|
||||
'params' => ['name' => $matches[1], 'mobile' => $matches[2]]
|
||||
];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* تجزیه پارامترهای دستور ابزار
|
||||
*/
|
||||
|
@ -263,7 +1030,11 @@ class AIService
|
|||
{
|
||||
$params = [];
|
||||
|
||||
// استخراج پارامترها از فرمت {name:value,key:value}
|
||||
// حذف نام ابزار از ابتدای دستور
|
||||
$command = preg_replace('/^\w+\{/', '', $command);
|
||||
$command = rtrim($command, '}');
|
||||
|
||||
// استخراج پارامترها از فرمت name:value,key:value
|
||||
if (preg_match_all('/([^:,}]+):([^,}]+)/u', $command, $matches, PREG_SET_ORDER)) {
|
||||
foreach ($matches as $match) {
|
||||
$key = trim($match[1]);
|
||||
|
@ -272,6 +1043,18 @@ class AIService
|
|||
// حذف کاراکترهای اضافی
|
||||
$value = rtrim($value, ',}');
|
||||
|
||||
// حذف فاصلههای اضافی
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
|
||||
// اصلاح کلیدهای نامعتبر
|
||||
if (strpos($key, '{') !== false) {
|
||||
$key = str_replace('{', '', $key);
|
||||
}
|
||||
if (strpos($key, 'edit_person') !== false) {
|
||||
$key = 'name';
|
||||
}
|
||||
|
||||
$params[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ class PersonTools
|
|||
public function addPerson(array $params, Business $business, $user): array
|
||||
{
|
||||
$name = $params['name'] ?? '';
|
||||
$fullName = $params['full_name'] ?? $name; // نام کامل (اختیاری)
|
||||
|
||||
if (empty($name)) {
|
||||
return [
|
||||
'success' => false,
|
||||
|
@ -38,7 +40,7 @@ class PersonTools
|
|||
];
|
||||
}
|
||||
|
||||
// بررسی وجود شخص با همین نام
|
||||
// بررسی وجود شخص با همین نام مستعار
|
||||
$existingPerson = $this->entityManager->getRepository(Person::class)->findOneBy([
|
||||
'nikename' => $name,
|
||||
'bid' => $business
|
||||
|
@ -47,14 +49,14 @@ class PersonTools
|
|||
if ($existingPerson) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => "شخصی با نام '{$name}' قبلاً وجود دارد."
|
||||
'error' => "شخصی با نام مستعار '{$name}' قبلاً وجود دارد."
|
||||
];
|
||||
}
|
||||
|
||||
// ایجاد شخص جدید
|
||||
$person = new Person();
|
||||
$person->setName($name);
|
||||
$person->setNikename($name);
|
||||
$person->setNikename($name); // نام مستعار (الزامی)
|
||||
$person->setName($fullName); // نام کامل (اختیاری)
|
||||
$person->setBid($business);
|
||||
|
||||
// تولید کد خودکار
|
||||
|
@ -138,6 +140,11 @@ class PersonTools
|
|||
$changes[] = "موبایل: {$params['phone']}";
|
||||
}
|
||||
|
||||
if (isset($params['mobile'])) {
|
||||
$person->setMobile($params['mobile']);
|
||||
$changes[] = "موبایل: {$params['mobile']}";
|
||||
}
|
||||
|
||||
if (isset($params['address'])) {
|
||||
$person->setAddress($params['address']);
|
||||
$changes[] = "آدرس: {$params['address']}";
|
||||
|
|
|
@ -76,23 +76,6 @@
|
|||
</template>
|
||||
<span>مشاهده آرشیو گفتگوها</span>
|
||||
</v-tooltip>
|
||||
|
||||
<!-- دکمه راهنمای عملیات -->
|
||||
<v-tooltip location="bottom">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn
|
||||
v-bind="props"
|
||||
icon
|
||||
@click="showOperationsGuide = true"
|
||||
class="mr-2 guide-btn"
|
||||
color="info"
|
||||
variant="tonal"
|
||||
>
|
||||
<v-icon>mdi-help-circle</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>راهنمای عملیات مدیریت اشخاص</span>
|
||||
</v-tooltip>
|
||||
</v-toolbar>
|
||||
<div class="page-container">
|
||||
<!-- کارت اطلاعات قیمتگذاری و آمار استفاده -->
|
||||
|
@ -202,6 +185,81 @@
|
|||
}">
|
||||
<div class="message-text" v-html="renderMarkdown(message.text)"></div>
|
||||
|
||||
<!-- Debug Info Section -->
|
||||
<div class="debug-info" v-if="message.debug_info">
|
||||
<div class="debug-header" @click="toggleDebugInfo(index)">
|
||||
<span>اطلاعات دیباگ</span>
|
||||
<span class="debug-toggle">{{ message.debug_info.expanded ? '▼' : '▶' }}</span>
|
||||
</div>
|
||||
<div class="debug-content" v-if="message.debug_info.expanded">
|
||||
<div class="debug-section" v-if="message.debug_info.operation_type">
|
||||
<h5>نوع عملیات:</h5>
|
||||
<p>{{ message.debug_info.operation_type }}</p>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.current_step">
|
||||
<h5>مرحله فعلی:</h5>
|
||||
<p>{{ message.debug_info.current_step }}</p>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.attempt_count">
|
||||
<h5>تعداد تلاش:</h5>
|
||||
<p>{{ message.debug_info.attempt_count }} از {{ message.debug_info.max_attempts }}</p>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.next_action">
|
||||
<h5>مرحله بعدی:</h5>
|
||||
<p>{{ message.debug_info.next_action }}</p>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.final_result">
|
||||
<h5>نتیجه نهایی:</h5>
|
||||
<p>{{ message.debug_info.final_result }}</p>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.final_data">
|
||||
<h5>دادههای نهایی:</h5>
|
||||
<pre>{{ JSON.stringify(message.debug_info.final_data, null, 2) }}</pre>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.json_response">
|
||||
<h5>پاسخ JSON:</h5>
|
||||
<pre>{{ JSON.stringify(message.debug_info.json_response, null, 2) }}</pre>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.tool_commands && message.debug_info.tool_commands.length > 0">
|
||||
<h5>دستورات ابزار یافت شده:</h5>
|
||||
<div v-for="(command, cmdIndex) in message.debug_info.tool_commands" :key="cmdIndex">
|
||||
<strong>{{ command.tool }}</strong>
|
||||
<pre>{{ JSON.stringify(command.params, null, 2) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.execution_result">
|
||||
<h5>نتیجه اجرا:</h5>
|
||||
<pre>{{ JSON.stringify(message.debug_info.execution_result, null, 2) }}</pre>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.execution_results">
|
||||
<h5>نتایج اجرای چندمرحلهای:</h5>
|
||||
<div v-for="(result, resultIndex) in message.debug_info.execution_results" :key="resultIndex">
|
||||
<strong>مرحله {{ resultIndex + 1 }}:</strong>
|
||||
<pre>{{ JSON.stringify(result, null, 2) }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.ai_response">
|
||||
<h5>پاسخ هوش مصنوعی:</h5>
|
||||
<pre>{{ message.debug_info.ai_response }}</pre>
|
||||
</div>
|
||||
|
||||
<div class="debug-section" v-if="message.debug_info.error">
|
||||
<h5>خطا:</h5>
|
||||
<p class="error">{{ message.debug_info.error }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- دکمه شارژ برای پیامهای خطای اعتبار -->
|
||||
<div v-if="message.showChargeButton" class="charge-button-container mt-3">
|
||||
<v-btn
|
||||
|
@ -433,32 +491,6 @@
|
|||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<!-- دیالوگ راهنمای عملیات -->
|
||||
<v-dialog v-model="showOperationsGuide" max-width="800px">
|
||||
<v-card>
|
||||
<v-card-title class="d-flex align-center justify-space-between">
|
||||
<span>راهنمای عملیات مدیریت اشخاص</span>
|
||||
<v-btn icon @click="showOperationsGuide = false">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-card-title>
|
||||
|
||||
<v-card-text>
|
||||
<div v-if="operationsGuide" v-html="renderMarkdown(operationsGuide)"></div>
|
||||
<div v-else class="text-center pa-4">
|
||||
<v-progress-circular indeterminate color="primary"></v-progress-circular>
|
||||
</div>
|
||||
</v-card-text>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="primary" @click="showOperationsGuide = false">
|
||||
بستن
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -522,9 +554,6 @@ export default {
|
|||
selectedPerson: null,
|
||||
personTransactions: [],
|
||||
showPersonInfo: false,
|
||||
// متغیرهای راهنمای عملیات
|
||||
showOperationsGuide: false,
|
||||
operationsGuide: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -564,7 +593,6 @@ export default {
|
|||
await this.checkConnection();
|
||||
await this.loadConversations();
|
||||
await this.loadBalance();
|
||||
await this.loadOperationsGuide(); // Add this line
|
||||
this.setWelcomeMessage();
|
||||
},
|
||||
methods: {
|
||||
|
@ -656,17 +684,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
async loadOperationsGuide() {
|
||||
try {
|
||||
const response = await axios.get('/api/wizard/persons/guide');
|
||||
if (response.data.success) {
|
||||
this.operationsGuide = response.data.guide;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('خطا در بارگذاری راهنما:', error);
|
||||
}
|
||||
},
|
||||
|
||||
formatBalance(balance) {
|
||||
// تبدیل به عدد صحیح
|
||||
const intBalance = Math.round(balance);
|
||||
|
@ -853,39 +870,38 @@ export default {
|
|||
});
|
||||
|
||||
if (response && response.data && response.data.success) {
|
||||
console.log('AI Response Data:', response.data);
|
||||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: response.data.response,
|
||||
usage: response.data.usage,
|
||||
cost: response.data.cost
|
||||
cost: response.data.cost,
|
||||
debug_info: response.data.debug_info ? {
|
||||
...response.data.debug_info,
|
||||
expanded: false
|
||||
} : null
|
||||
});
|
||||
// بهروزرسانی اعتبار کاربر
|
||||
await this.loadBalance();
|
||||
// بهروزرسانی لیست گفتگوها
|
||||
await this.loadConversations();
|
||||
this.$emit('show-snackbar', {
|
||||
text: 'پاسخ دریافت شد',
|
||||
color: 'success'
|
||||
});
|
||||
} else if (response && response.data) {
|
||||
// بررسی خطای اعتبار
|
||||
if (response.data.error && response.data.error.includes('اعتبار')) {
|
||||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: `خطا: ${response.data.error}`,
|
||||
isError: true,
|
||||
showChargeButton: response.data.showChargeButton || false
|
||||
});
|
||||
await this.loadBalance();
|
||||
} else {
|
||||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: `خطا: ${response.data.error}`,
|
||||
isError: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// اگر هیچ پاسخی از سرور دریافت نشد
|
||||
console.log('AI Error Response:', response.data);
|
||||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: 'خطا: خطا در ارتباط با سرور',
|
||||
isError: true
|
||||
text: `خطا: ${response.data.error}`,
|
||||
isError: true,
|
||||
debug_info: response.data.debug_info || null
|
||||
});
|
||||
} else {
|
||||
console.log('No response data');
|
||||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: 'خطا در ارتباط با سرور',
|
||||
isError: true,
|
||||
debug_info: null
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
|
@ -893,7 +909,8 @@ export default {
|
|||
this.userMessages.push({
|
||||
isAI: true,
|
||||
text: 'خطا: خطا در ارتباط با سرور',
|
||||
isError: true
|
||||
isError: true,
|
||||
debug_info: null
|
||||
});
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
|
@ -1029,6 +1046,12 @@ export default {
|
|||
color: 'error'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
toggleDebugInfo(index) {
|
||||
if (this.userMessages[index] && this.userMessages[index].debug_info) {
|
||||
this.userMessages[index].debug_info.expanded = !this.userMessages[index].debug_info.expanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1303,4 +1326,78 @@ export default {
|
|||
.send-icon-rotate {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* استایلهای Debug Info */
|
||||
.debug-info-section {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.debug-panel-title {
|
||||
font-size: 0.875rem;
|
||||
font-weight: 500;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.debug-content {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.debug-section h4 {
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.debug-card {
|
||||
background: #fafafa;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.debug-text {
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.4;
|
||||
color: #333;
|
||||
background: #f5f5f5;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.command-item {
|
||||
border-left: 3px solid #1a237e;
|
||||
padding-left: 12px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.command-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.command-header .text-caption {
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* استایلهای Manual Commands */
|
||||
.manual-commands-section {
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.manual-commands-section h4 {
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.manual-commands-section .v-btn {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in a new issue