logdetective 2.4.1__py3-none-any.whl → 2.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,15 +57,15 @@ Please know that the explanation was provided by AI and may be incorrect.
57
57
  </li>
58
58
  </ul>
59
59
  </details>
60
- ---
61
- This comment was created by [Log Detective][log-detective].
60
+
61
+ <hr>
62
+
63
+ This comment was created by <a href="https://logdetective.com">Log Detective</a>.
62
64
  Was the provided feedback accurate and helpful?
63
65
  <br>
64
66
  Please vote with :thumbsup:
65
67
  or :thumbsdown: to help us improve.
66
68
  <br>
67
- <i>If this Log Detective report contains harmful content, please use the
68
- [Gitlab reporting feature for harmful content](https://docs.gitlab.com/user/report_abuse/)
69
- and contact the [Log Detective developers](https://github.com/fedora-copr/logdetective/issues).</i>
70
- [log-detective]: https://log-detective.com/
71
- [contact]: https://github.com/fedora-copr
69
+ <i>If this Log Detective report contains harmful content,
70
+ please use the <a href="https://docs.gitlab.com/user/report_abuse/">Gitlab reporting feature for harmful content</a>
71
+ and contact the <a href="https://github.com/fedora-copr/logdetective/issues">Log Detective developers</a>.</i>
@@ -46,15 +46,15 @@ Please know that the explanation was provided by AI and may be incorrect.
46
46
  </li>
47
47
  </ul>
48
48
  </details>
49
- ---
50
- This comment was created by [Log Detective][log-detective].
49
+
50
+ <hr>
51
+
52
+ This comment was created by <a href="https://logdetective.com">Log Detective</a>.
51
53
  Was the provided feedback accurate and helpful?
52
54
  <br>
53
55
  Please vote with :thumbsup:
54
56
  or :thumbsdown: to help us improve.
55
57
  <br>
56
- <i>If this Log Detective report contains harmful content, please use the
57
- [Gitlab reporting feature for harmful content](https://docs.gitlab.com/user/report_abuse/)
58
- and contact the [Log Detective developers](https://github.com/fedora-copr/logdetective/issues).</i>
59
- [log-detective]: https://log-detective.com/
60
- [contact]: https://github.com/fedora-copr
58
+ <i>If this Log Detective report contains harmful content,
59
+ please use the <a href="https://docs.gitlab.com/user/report_abuse/">Gitlab reporting feature for harmful content</a>
60
+ and contact the <a href="https://github.com/fedora-copr/logdetective/issues">Log Detective developers</a>.</i>
@@ -1,7 +1,9 @@
1
1
  from typing import List
2
+ from importlib.metadata import version
2
3
 
3
4
  import aiohttp
4
5
  from fastapi import HTTPException
6
+ from fastapi.responses import Response as BasicResponse
5
7
 
6
8
  from logdetective.constants import SNIPPET_DELIMITER
7
9
  from logdetective.server.config import LOG
@@ -102,3 +104,8 @@ def construct_final_prompt(formatted_snippets: str, prompt_template: str) -> str
102
104
 
103
105
  final_prompt = prompt_template.format(formatted_snippets)
104
106
  return final_prompt
107
+
108
+
109
+ def get_version() -> BasicResponse:
110
+ """Obtain the version number using importlib"""
111
+ return BasicResponse(content=version('logdetective'))
logdetective/utils.py CHANGED
@@ -16,54 +16,61 @@ from logdetective.remote_log import RemoteLog
16
16
  LOG = logging.getLogger("logdetective")
17
17
 
18
18
 
19
- def chunk_continues(text: str, index: int) -> bool:
19
+ def new_message(text: str) -> bool:
20
20
  """Set of heuristics for determining whether or not
21
21
  does the current chunk of log text continue on next line.
22
22
 
23
23
  Following rules are checked, in order:
24
- * is the next character is whitespace
25
- * is the previous character backslash '\\'
26
- * is the previous character colon ':'
27
-
24
+ * is the first character is whitespace
25
+ * is the first character backslash '|'
28
26
  """
29
27
  conditionals = [
30
- lambda i, string: string[i + 1].isspace(),
31
- lambda i, string: string[i - 1] == "\\",
32
- lambda i, string: string[i - 1] == ":",
28
+ lambda string: string[0].isspace(),
29
+ lambda string: string[0] == "|",
33
30
  ]
34
31
 
35
32
  for c in conditionals:
36
- y = c(index, text)
33
+ y = c(text)
37
34
  if y:
38
- return True
35
+ return False
39
36
 
40
- return False
37
+ return True
41
38
 
42
39
 
43
40
  def get_chunks(
44
- text: str, max_len: int = 2000
41
+ text: str, max_chunk_len: int = 2000
45
42
  ) -> Generator[Tuple[int, str], None, None]:
46
43
  """Split log into chunks according to heuristic
47
44
  based on whitespace and backslash presence.
48
45
  """
49
- text_len = len(text)
50
- i = 0
46
+ lines = text.splitlines()
47
+
48
+ # Chunk we will be yielding
51
49
  chunk = ""
52
- # Keep track of the original and next line number
53
- # every `\n` hit increases the next_line_number by one.
54
- original_line_number = 0
55
- next_line_number = 0
56
- while i < text_len:
57
- chunk += text[i]
58
- if text[i] == "\n":
59
- next_line_number += 1
60
- if i + 1 < text_len and chunk_continues(text, i) and i + 1 < max_len:
61
- i += 1
62
- continue
63
- yield (original_line_number, chunk)
64
- original_line_number = next_line_number + 1
65
- chunk = ""
66
- i += 1
50
+ # Number of line where the message started
51
+ original_line = 0
52
+ for i, line in enumerate(lines):
53
+ if len(line) == 0:
54
+ continue
55
+ if new_message(line):
56
+ # Yield chunk if we have it
57
+ if len(chunk) > 0:
58
+ yield (original_line, chunk)
59
+ original_line = i
60
+ chunk = line
61
+ else:
62
+ chunk += "\n" + line
63
+ if len(chunk) > max_chunk_len:
64
+ # If the chunk is too long, keep splitting into smaller chunks
65
+ # until we reach manageable size
66
+ while len(chunk) > max_chunk_len:
67
+ remainder = chunk[max_chunk_len:]
68
+ chunk = chunk[:max_chunk_len]
69
+ yield (original_line, chunk)
70
+ chunk = remainder
71
+
72
+ # if we still have some text left over
73
+ yield (original_line, chunk)
67
74
 
68
75
 
69
76
  def initialize_model(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: logdetective
3
- Version: 2.4.1
3
+ Version: 2.6.0
4
4
  Summary: Log using LLM AI to search for build/test failures and provide ideas for fixing these.
5
5
  License: Apache-2.0
6
6
  License-File: LICENSE
@@ -27,6 +27,8 @@ Requires-Dist: aiohttp (>=3.7.4,<4.0.0)
27
27
  Requires-Dist: aiolimiter (>=1.0.0,<2.0.0) ; extra == "server"
28
28
  Requires-Dist: aioresponses (>=0.7.8,<0.8.0) ; extra == "testing"
29
29
  Requires-Dist: alembic (>=1.13.3,<2.0.0) ; extra == "server" or extra == "server-testing"
30
+ Requires-Dist: asciidoc[testing] (>=10.2.1,<11.0.0) ; extra == "testing"
31
+ Requires-Dist: asyncpg (>=0.30.0,<0.31.0) ; extra == "server" or extra == "server-testing"
30
32
  Requires-Dist: backoff (==2.2.1) ; extra == "server" or extra == "server-testing"
31
33
  Requires-Dist: drain3 (>=0.9.11,<0.10.0)
32
34
  Requires-Dist: fastapi (>=0.111.1,<1.0.0) ; extra == "server" or extra == "server-testing"
@@ -37,11 +39,10 @@ Requires-Dist: llama-cpp-python (>0.2.56,!=0.2.86,<1.0.0)
37
39
  Requires-Dist: matplotlib (>=3.8.4,<4.0.0) ; extra == "server" or extra == "server-testing"
38
40
  Requires-Dist: numpy (>=1.26.0)
39
41
  Requires-Dist: openai (>=1.82.1,<2.0.0) ; extra == "server" or extra == "server-testing"
40
- Requires-Dist: psycopg2 (>=2.9.9,<3.0.0) ; extra == "server"
41
- Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0) ; extra == "server-testing"
42
42
  Requires-Dist: pydantic (>=2.8.2,<3.0.0)
43
43
  Requires-Dist: pytest (>=8.4.1,<9.0.0) ; extra == "testing"
44
44
  Requires-Dist: pytest-asyncio (>=1.1.0,<2.0.0) ; extra == "testing"
45
+ Requires-Dist: pytest-cov[testing] (>=7.0.0,<8.0.0) ; extra == "testing"
45
46
  Requires-Dist: pytest-mock (>=3.14.1,<4.0.0) ; extra == "server-testing"
46
47
  Requires-Dist: python-gitlab (>=4.4.0)
47
48
  Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
@@ -127,6 +128,20 @@ Note that streaming with some models (notably Meta-Llama-3) is broken and can be
127
128
 
128
129
  logdetective https://example.com/logs.txt --model QuantFactory/Meta-Llama-3-8B-Instruct-GGUF --filename_suffix Q5_K_M.gguf --no-stream
129
130
 
131
+ Choice of LLM
132
+ -------------
133
+
134
+ While Log Detective is compatible with a wide range of LLMs, it does require an instruction tuned model to function properly.
135
+
136
+ Whether or not the model has been trained to work with instructions can be determined by examining the model card, or simply by checking if it has `instruct` in its name.
137
+
138
+ When deployed as a server, Log Detective uses `/chat/completions` API as defined by OpenAI. The API must support both `system` and `user` roles, in order to properly work with a system prompt.
139
+
140
+ Configuration fields `system_role` and `user_role` can be used to set role names for APIs with non-standard roles.
141
+
142
+ > **Note:**
143
+ > In cases when no system role is available, it is possible to set both fields to the same value. This will concatenate system and standard prompt.
144
+ > This may have negative impact coherence of response.
130
145
 
131
146
  Real Example
132
147
  ------------
@@ -4,37 +4,37 @@ logdetective/drain3.ini,sha256=ni91eCT1TwTznZwcqWoOVMQcGEnWhEDNCoTPF7cfGfY,1360
4
4
  logdetective/extractors.py,sha256=vT-je4NkDgSj9rRtSeLpqBU52gIUnnVgJPHFbVihpCw,5993
5
5
  logdetective/logdetective.py,sha256=Ck7TL3YvdQG8zniudM8bM51LfTyVW6Ea3BarTjzjWHo,6606
6
6
  logdetective/models.py,sha256=uczmQtWFgSp_ZGssngdTM4qzPF1o64dCy0469GoSbjQ,2937
7
- logdetective/prompts-summary-first.yml,sha256=3Zfp4NNOfaFYq5xBlBjeQa5PdjYfS4v17OtJqQ-DRpU,821
7
+ logdetective/prompts-summary-first.yml,sha256=kmyMFQmqFXpojkz7p3CyCWCPxMpFLpfDdMGisB4YwL0,808
8
8
  logdetective/prompts-summary-only.yml,sha256=8U9AMJV8ePW-0CoXOXlQoO92DAJDeutIT8ntSkkm6W0,470
9
- logdetective/prompts.yml,sha256=Mq8RdWgJxxhrQYgammojJkXULJNpzSLU0N_BryOxKgc,3906
9
+ logdetective/prompts.yml,sha256=i3z6Jcb4ScVi7LsxOpDlKiXrcvql3qO_JnLzkAKMn1c,3870
10
10
  logdetective/remote_log.py,sha256=28QvdQiy7RBnd86EKCq_A75P21gSNlCbgxJe5XAe9MA,2258
11
11
  logdetective/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  logdetective/server/compressors.py,sha256=qzrT-BPSksXY6F2L6ger04GGrgdBsGOfK2YuCFRs0Q4,5427
13
13
  logdetective/server/config.py,sha256=cKUmNCJyNyEid0bPTiUjr8CQuBYBab5bC79Axk2h0z8,2525
14
14
  logdetective/server/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- logdetective/server/database/base.py,sha256=1mcjEbhwLl4RalvT3oy6XVctjJoWIW3H9aI_sMWJBK8,1728
16
- logdetective/server/database/models/__init__.py,sha256=GQ_4vC_jahwFrqhF4UUKLRo86_ulq1uSBAF3Je31DyA,878
15
+ logdetective/server/database/base.py,sha256=HSV2tgye7iYTDzJD1Q5X7_nlLuTMIFP-hRVQMYxngHQ,2073
16
+ logdetective/server/database/models/__init__.py,sha256=zoZMCt1_7tewDa6eEIIX_xrdN-tLegSiPNg5NiYaV3o,850
17
17
  logdetective/server/database/models/exceptions.py,sha256=AXQPZRgt-r2vboxP9SGYelngP6YIFpHlwELKcZ1FD3Y,384
18
- logdetective/server/database/models/koji.py,sha256=vZN585FvOHM4z5o3oBBQsxWWJER1_giOMtZZPiU4q3w,5457
19
- logdetective/server/database/models/merge_request_jobs.py,sha256=q4reSC7YnEfWBPpV-qNt5nvuq0drntisHnKkFOlQW0o,18614
20
- logdetective/server/database/models/metrics.py,sha256=_UCaizcl9w4iX54EWvk5VvXeLcg2UfnQgXg4br3OLko,14214
21
- logdetective/server/emoji.py,sha256=hV4O0yfL0l1a3kWLImvBsY4AJQauKs7okYOGBEtYVz0,4795
18
+ logdetective/server/database/models/koji.py,sha256=3soiJQ3L-H09cVO-BeRDEcP-HrSa-Z6qp3kwePUZsbo,6216
19
+ logdetective/server/database/models/merge_request_jobs.py,sha256=MxiAVKQIsQMbFylBsmYBmVXYvid-4_5mwwXLfWdp6_w,19965
20
+ logdetective/server/database/models/metrics.py,sha256=zzTRo67qwLyDj1GKbclZm1UXt1nNU-G662-y5XyGshE,15458
21
+ logdetective/server/emoji.py,sha256=CoaAiZA_JgtUJe41YOsQRqd_QpgVeQ8szJt_bQ3d_JM,4837
22
22
  logdetective/server/exceptions.py,sha256=piV7wVKc-rw_pHrThbZbUjtmjuO5qUbjVNFwjdfcP3Q,864
23
- logdetective/server/gitlab.py,sha256=hPQICeYK1B_1BS56GIExQgEhcdS5Y6IgBCkk-eXtnDY,16708
23
+ logdetective/server/gitlab.py,sha256=putpnf8PfGsCZJsqWZA1rMovRGnyagoQmgpKLqtA-aQ,16743
24
24
  logdetective/server/koji.py,sha256=LG1pRiKUFvYFRKzgQoUG3pUHfcEwMoaMNjUSMKw_pBA,5640
25
25
  logdetective/server/llm.py,sha256=bmA6LsV80OdO60q4WLoKuehuVDEYq-HhBAYcZeLfrv8,10150
26
- logdetective/server/metric.py,sha256=QrrX1FmMa7sc57av0P9UFOiCIFYVLs1opOWV3ObYo0s,4086
26
+ logdetective/server/metric.py,sha256=-gqdd6LBUs_K6Sk30TZ7FJYE7Htp8d-uhVY5NwYgD3g,4186
27
27
  logdetective/server/models.py,sha256=BoiiUYI6BcVDOqtIcUgNRsCyjcWNCKyEfVtYOLYgr1Y,20929
28
- logdetective/server/plot.py,sha256=C98U9prGoPkp8_t4v2dovdZuwOhSbxXSeB_K9Q2r3NE,14607
29
- logdetective/server/server.py,sha256=s1QtD6FYsQX7BaVi783v7sqCEk4ccqlBJHFKUQlGgWM,24684
28
+ logdetective/server/plot.py,sha256=lFKOTXlLJ3aZtZGYXceA4OqUt1z18BpLITTI39fOMx4,14685
29
+ logdetective/server/server.py,sha256=Qx8mqkrRq-nlOnmOmICbaXxUWq2J60K4dHKiJtQJuE0,24938
30
30
  logdetective/server/templates/base_response.html.j2,sha256=BJGGV_Xb0Lnue8kq32oG9lI5CQDf9vce7HMYsP-Pvb4,2040
31
- logdetective/server/templates/gitlab_full_comment.md.j2,sha256=eNX_ZkAAVV7nNfKe02g_1-GgbiSqim0JH4aF3anzmxE,2186
32
- logdetective/server/templates/gitlab_short_comment.md.j2,sha256=UpQxIgOuOO8BBF__kzFl0XlCuYmcyfN2yMz6vd4PQ2Q,2000
33
- logdetective/server/utils.py,sha256=7ub-Nz7LUP_idwi2_nEC4FBuY9otSBUVy9nw86-sjYc,3861
31
+ logdetective/server/templates/gitlab_full_comment.md.j2,sha256=hSWEj_a7KZpzfbgoPhWA9KBwa25daDCb6S3cuBqclss,2143
32
+ logdetective/server/templates/gitlab_short_comment.md.j2,sha256=d396HR2DJuS8XLu2FNgVAg1CrOW8_LySQX2f6opOjp8,1957
33
+ logdetective/server/utils.py,sha256=KiyzzUIVssBc61LhGS0QNC5EY29In3NsG9j58ZRtoNI,4104
34
34
  logdetective/skip_snippets.yml,sha256=reGlhPPCo06nNUJWiC2LY-OJOoPdcyOB7QBTSMeh0eg,487
35
- logdetective/utils.py,sha256=9EyHKGNxtS1ObSepL-T3M43rKIxQJkFDA5yllLbS5Bs,9178
36
- logdetective-2.4.1.dist-info/METADATA,sha256=wBT_T5szJE3Xnn76UvC4drCacVhgCaBQ0QZkrBbpjnk,21645
37
- logdetective-2.4.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
- logdetective-2.4.1.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
39
- logdetective-2.4.1.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
40
- logdetective-2.4.1.dist-info/RECORD,,
35
+ logdetective/utils.py,sha256=4B9wwaM4tyxLFtRnnTRDcGULJDonp6VoUS8HvUpIeSI,9388
36
+ logdetective-2.6.0.dist-info/METADATA,sha256=hLRUiBvOeyWn6t9qkRVEx3nLuNmysSoReXL6aFBECsg,22598
37
+ logdetective-2.6.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
38
+ logdetective-2.6.0.dist-info/entry_points.txt,sha256=3K_vXja6PmcA8sNdUi63WdImeiNhVZcEGPTaoJmltfA,63
39
+ logdetective-2.6.0.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
40
+ logdetective-2.6.0.dist-info/RECORD,,