DocUA commited on
Commit
10a9a4e
·
1 Parent(s): fb9ceee

робочий варіант AI Аналізу

Browse files
interface.py CHANGED
@@ -15,9 +15,10 @@ def launch_interface(app):
15
  app: Екземпляр JiraAssistantApp
16
  """
17
  # Функція для обробки завантаження та аналізу CSV
 
18
  def analyze_csv(file_obj, inactive_days, include_ai):
19
  if file_obj is None:
20
- return "Помилка: файл не вибрано", None, None, None, None
21
 
22
  try:
23
  logger.info(f"Отримано файл: {file_obj.name}, тип: {type(file_obj)}")
@@ -54,13 +55,10 @@ def launch_interface(app):
54
  pass
55
 
56
  if result.get("error"):
57
- return result.get("error"), None, None, None, None
58
 
59
  return (
60
  result.get("report", ""),
61
- result.get("visualizations", {}).get("status"),
62
- result.get("visualizations", {}).get("priority"),
63
- result.get("visualizations", {}).get("created_timeline"),
64
  result.get("ai_analysis", "AI аналіз буде доступний у наступних версіях додатку.")
65
  )
66
 
@@ -68,7 +66,7 @@ def launch_interface(app):
68
  import traceback
69
  error_msg = f"Помилка аналізу: {str(e)}\n\n{traceback.format_exc()}"
70
  logger.error(error_msg)
71
- return error_msg, None, None, None, None
72
 
73
  # Функція для збереження звіту
74
  def save_report_handler(report_text, format_type, include_visualizations):
@@ -235,13 +233,6 @@ def launch_interface(app):
235
  with gr.Tab("Звіт"):
236
  report_output = gr.Markdown()
237
 
238
- with gr.Tab("Візуалізації"):
239
- with gr.Row():
240
- status_plot = gr.Plot(label="Статуси тікетів")
241
- priority_plot = gr.Plot(label="Пріоритети тікетів")
242
-
243
- timeline_plot = gr.Plot(label="Часова шкала")
244
-
245
  with gr.Tab("AI Аналіз"):
246
  ai_output = gr.Markdown()
247
 
@@ -249,7 +240,7 @@ def launch_interface(app):
249
  analyze_btn.click(
250
  analyze_csv,
251
  inputs=[file_input, inactive_days, include_ai],
252
- outputs=[report_output, status_plot, priority_plot, timeline_plot, ai_output]
253
  )
254
 
255
  save_btn.click(
 
15
  app: Екземпляр JiraAssistantApp
16
  """
17
  # Функція для обробки завантаження та аналізу CSV
18
+ # Змініть функцію analyze_csv, щоб вона повертала тільки звіт та AI аналіз
19
  def analyze_csv(file_obj, inactive_days, include_ai):
20
  if file_obj is None:
21
+ return "Помилка: файл не вибрано", None
22
 
23
  try:
24
  logger.info(f"Отримано файл: {file_obj.name}, тип: {type(file_obj)}")
 
55
  pass
56
 
57
  if result.get("error"):
58
+ return result.get("error"), None
59
 
60
  return (
61
  result.get("report", ""),
 
 
 
62
  result.get("ai_analysis", "AI аналіз буде доступний у наступних версіях додатку.")
63
  )
64
 
 
66
  import traceback
67
  error_msg = f"Помилка аналізу: {str(e)}\n\n{traceback.format_exc()}"
68
  logger.error(error_msg)
69
+ return error_msg, None
70
 
71
  # Функція для збереження звіту
72
  def save_report_handler(report_text, format_type, include_visualizations):
 
233
  with gr.Tab("Звіт"):
234
  report_output = gr.Markdown()
235
 
 
 
 
 
 
 
 
236
  with gr.Tab("AI Аналіз"):
237
  ai_output = gr.Markdown()
238
 
 
240
  analyze_btn.click(
241
  analyze_csv,
242
  inputs=[file_input, inactive_days, include_ai],
243
+ outputs=[report_output, ai_output]
244
  )
245
 
246
  save_btn.click(
modules/ai_analysis/llm_connector.py CHANGED
@@ -18,7 +18,7 @@ class LLMConnector:
18
 
19
  Args:
20
  api_key (str): API ключ для доступу до LLM.
21
- Якщо None, спробує використати змінну середовища.
22
  model_type (str): Тип моделі ("openai" або "gemini")
23
  """
24
  self.model_type = model_type.lower()
@@ -29,8 +29,12 @@ class LLMConnector:
29
  if not self.api_key:
30
  logger.warning("API ключ OpenAI не вказано")
31
 
32
- self.model = "gpt-3.5-turbo" # Стандартна модель
33
- openai.api_key = self.api_key
 
 
 
 
34
 
35
  elif self.model_type == "gemini":
36
  self.api_key = api_key or os.getenv("GEMINI_API_KEY")
@@ -38,7 +42,7 @@ class LLMConnector:
38
  if not self.api_key:
39
  logger.warning("API ключ Gemini не вказано")
40
 
41
- self.model = "gemini-pro" # Стандартна модель для Gemini
42
 
43
  else:
44
  raise ValueError(f"Непідтримуваний тип моделі: {model_type}")
@@ -150,18 +154,26 @@ class LLMConnector:
150
  if not self.api_key:
151
  return "Не вказано API ключ OpenAI"
152
 
153
- # Створення запиту до LLM
154
- response = openai.chat.completions.create(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  model=self.model,
156
- messages=[
157
- {"role": "system", "content": """Ви аналітик Jira з досвідом у процесах розробки ПЗ.
158
- Проаналізуйте надані дані про тікети та надайте корисні інсайти та рекомендації
159
- для покращення процесу. Будьте конкретними та орієнтованими на дії.
160
- Виділіть сильні та слабкі сторони, а також потенційні ризики та можливості.
161
- Аналіз повинен бути структурованим і легким для сприйняття менеджерами проекту."""},
162
- {"role": "user", "content": f"Проаналізуйте наступні дані Jira та надайте рекомендації:\n\n{data_summary}"}
163
- ],
164
  temperature=temperature,
 
165
  )
166
 
167
  # Отримання результату
@@ -271,7 +283,7 @@ class LLMConnector:
271
  messages.append({"role": "user", "content": question})
272
 
273
  # Відправлення запиту
274
- response = openai.chat.completions.create(
275
  model=self.model,
276
  messages=messages,
277
  temperature=temperature,
@@ -314,7 +326,7 @@ class LLMConnector:
314
  else:
315
  format_instruction = "Створіть звіт у простому текстовому форматі."
316
 
317
- response = openai.chat.completions.create(
318
  model=self.model,
319
  messages=[
320
  {"role": "system", "content": f"""Ви аналітик, який створює професійні звіти на основі даних Jira.
@@ -443,7 +455,7 @@ class AIAgentManager:
443
 
444
  # Відправлення запиту до LLM
445
  if self.llm_connector.model_type == "openai":
446
- response = openai.chat.completions.create(
447
  model=self.llm_connector.model,
448
  messages=messages,
449
  temperature=temperature,
@@ -456,8 +468,54 @@ class AIAgentManager:
456
  return result
457
 
458
  elif self.llm_connector.model_type == "gemini":
459
- # TODO: Реалізувати для Gemini
460
- return f"Gemini API для агента '{agent_name}' ще не реалізовано"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
 
462
  except Exception as e:
463
  logger.error(f"Помилка при виконанні задачі агентом '{agent_name}': {e}")
 
18
 
19
  Args:
20
  api_key (str): API ключ для доступу до LLM.
21
+ Якщо None, спробує використати змінну середовища.
22
  model_type (str): Тип моделі ("openai" або "gemini")
23
  """
24
  self.model_type = model_type.lower()
 
29
  if not self.api_key:
30
  logger.warning("API ключ OpenAI не вказано")
31
 
32
+ self.model = "gpt-4o-mini" # Оновлено стандартну модель
33
+
34
+ # Використовуємо новий спосіб ініціалізації клієнта OpenAI
35
+ # без проксі та інших застарілих параметрів
36
+ from openai import OpenAI
37
+ self.client = OpenAI(api_key=self.api_key)
38
 
39
  elif self.model_type == "gemini":
40
  self.api_key = api_key or os.getenv("GEMINI_API_KEY")
 
42
  if not self.api_key:
43
  logger.warning("API ключ Gemini не вказано")
44
 
45
+ self.model = "gemini-2.0-flash" # Оновлена модель для Gemini
46
 
47
  else:
48
  raise ValueError(f"Непідтримуваний тип моделі: {model_type}")
 
154
  if not self.api_key:
155
  return "Не вказано API ключ OpenAI"
156
 
157
+ # Створення запиту до LLM з новим API
158
+ system_prompt = """Ви аналітик Jira з досвідом у процесах розробки ПЗ.
159
+ Проаналізуйте надані дані про тікети та надайте корисні інсайти та рекомендації
160
+ для покращення процесу. Будьте конкретними та орієнтованими на дії.
161
+ Виділіть сильні та слабкі сторони, а також потенційні ризики та можливості.
162
+ Аналіз повинен бути структурованим і легким для сприйняття менеджерами проекту."""
163
+
164
+ user_prompt = f"Проаналізуйте наступні дані Jira та надайте рекомендації:\n\n{data_summary}"
165
+
166
+ messages = [
167
+ {"role": "system", "content": system_prompt},
168
+ {"role": "user", "content": user_prompt}
169
+ ]
170
+
171
+ # Надсилання запиту через новий клієнт OpenAI
172
+ response = self.client.chat.completions.create(
173
  model=self.model,
174
+ messages=messages,
 
 
 
 
 
 
 
175
  temperature=temperature,
176
+ max_tokens=2048
177
  )
178
 
179
  # Отримання результату
 
283
  messages.append({"role": "user", "content": question})
284
 
285
  # Відправлення запиту
286
+ response = self.client.chat.completions.create(
287
  model=self.model,
288
  messages=messages,
289
  temperature=temperature,
 
326
  else:
327
  format_instruction = "Створіть звіт у простому текстовому форматі."
328
 
329
+ response = self.client.chat.completions.create(
330
  model=self.model,
331
  messages=[
332
  {"role": "system", "content": f"""Ви аналітик, який створює професійні звіти на основі даних Jira.
 
455
 
456
  # Відправлення запиту до LLM
457
  if self.llm_connector.model_type == "openai":
458
+ response = self.llm_connector.client.chat.completions.create(
459
  model=self.llm_connector.model,
460
  messages=messages,
461
  temperature=temperature,
 
468
  return result
469
 
470
  elif self.llm_connector.model_type == "gemini":
471
+ # Реалізуємо запит до Gemini API через прямий HTTP запит
472
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{self.llm_connector.model}:generateContent?key={self.llm_connector.api_key}"
473
+
474
+ # Формування системного промпта та запиту користувача
475
+ system_prompt = agent["system_prompt"]
476
+ user_content = ""
477
+
478
+ if context:
479
+ user_content += f"Контекст: {context}\n\n"
480
+
481
+ user_content += task
482
+
483
+ # Формування повного запиту
484
+ payload = {
485
+ "contents": [
486
+ {
487
+ "parts": [
488
+ {
489
+ "text": f"{system_prompt}\n\n{user_content}"
490
+ }
491
+ ]
492
+ }
493
+ ],
494
+ "generationConfig": {
495
+ "temperature": temperature,
496
+ "maxOutputTokens": 2048
497
+ }
498
+ }
499
+
500
+ # Відправлення запиту
501
+ headers = {"Content-Type": "application/json"}
502
+ response = requests.post(url, headers=headers, json=payload)
503
+
504
+ # Обробка відповіді
505
+ if response.status_code == 200:
506
+ response_data = response.json()
507
+
508
+ # Отримання тексту відповіді
509
+ if 'candidates' in response_data and len(response_data['candidates']) > 0:
510
+ if 'content' in response_data['candidates'][0]:
511
+ content = response_data['candidates'][0]['content']
512
+ if 'parts' in content and len(content['parts']) > 0:
513
+ result = content['parts'][0].get('text', '')
514
+ logger.info(f"Успішно отримано результат від агента '{agent_name}' (Gemini)")
515
+ return result
516
+
517
+ logger.error(f"Помилка при запиті до Gemini API: {response.text}")
518
+ return f"Помилка при запиті до Gemini API: статус {response.status_code}"
519
 
520
  except Exception as e:
521
  logger.error(f"Помилка при виконанні задачі агентом '{agent_name}': {e}")
requirements.txt CHANGED
@@ -1,9 +1,12 @@
1
- gradio==5.19.0
2
- jira==3.5.2
3
- pandas==2.1.0
4
- numpy==1.26.0
5
- matplotlib==3.7.2
6
- seaborn==0.12.2
7
- python-dotenv==1.0.0
8
- markdown==3.4.4
9
- pathlib==1.0.1
 
 
 
 
1
+ gradio>=5.19.0
2
+ jira>=3.5.2
3
+ pandas>=2.1.0
4
+ numpy>=1.26.0
5
+ matplotlib>=3.7.2
6
+ seaborn>=0.12.2
7
+ python-dotenv>=1.0.0
8
+ markdown>=3.4.4
9
+ pathlib>=1.0.1
10
+ google-generativeai>=0.3.2
11
+ openai>=1.12.0
12
+ httpx>=0.27.0