holmesgpt 0.14.2__py3-none-any.whl → 0.14.4a0__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.
Potentially problematic release.
This version of holmesgpt might be problematic. Click here for more details.
- holmes/__init__.py +1 -1
- holmes/common/env_vars.py +6 -0
- holmes/config.py +3 -6
- holmes/core/conversations.py +12 -2
- holmes/core/feedback.py +191 -0
- holmes/core/llm.py +16 -12
- holmes/core/models.py +101 -1
- holmes/core/supabase_dal.py +23 -9
- holmes/core/tool_calling_llm.py +197 -15
- holmes/core/tools.py +20 -7
- holmes/core/tools_utils/token_counting.py +13 -0
- holmes/core/tools_utils/tool_context_window_limiter.py +45 -23
- holmes/core/tools_utils/tool_executor.py +11 -6
- holmes/core/toolset_manager.py +5 -1
- holmes/core/truncation/dal_truncation_utils.py +23 -0
- holmes/interactive.py +146 -14
- holmes/plugins/prompts/_fetch_logs.jinja2 +3 -0
- holmes/plugins/runbooks/__init__.py +6 -1
- holmes/plugins/toolsets/__init__.py +11 -4
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +9 -20
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +6 -4
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +6 -4
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +6 -4
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +2 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +2 -3
- holmes/plugins/toolsets/bash/bash_toolset.py +4 -7
- holmes/plugins/toolsets/cilium.yaml +284 -0
- holmes/plugins/toolsets/datadog/toolset_datadog_general.py +5 -10
- holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +1 -1
- holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +6 -13
- holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +3 -6
- holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +4 -9
- holmes/plugins/toolsets/git.py +14 -12
- holmes/plugins/toolsets/grafana/grafana_tempo_api.py +23 -42
- holmes/plugins/toolsets/grafana/toolset_grafana.py +2 -3
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +18 -36
- holmes/plugins/toolsets/internet/internet.py +2 -3
- holmes/plugins/toolsets/internet/notion.py +2 -3
- holmes/plugins/toolsets/investigator/core_investigation.py +7 -9
- holmes/plugins/toolsets/kafka.py +7 -18
- holmes/plugins/toolsets/logging_utils/logging_api.py +79 -3
- holmes/plugins/toolsets/mcp/toolset_mcp.py +2 -3
- holmes/plugins/toolsets/newrelic/__init__.py +0 -0
- holmes/plugins/toolsets/newrelic/new_relic_api.py +125 -0
- holmes/plugins/toolsets/newrelic/newrelic.jinja2 +41 -0
- holmes/plugins/toolsets/newrelic/newrelic.py +211 -0
- holmes/plugins/toolsets/opensearch/opensearch.py +5 -12
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +3 -6
- holmes/plugins/toolsets/prometheus/prometheus.py +135 -98
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +3 -6
- holmes/plugins/toolsets/robusta/robusta.py +4 -9
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +93 -13
- holmes/plugins/toolsets/servicenow/servicenow.py +5 -10
- holmes/utils/sentry_helper.py +1 -1
- holmes/utils/stream.py +22 -7
- holmes/version.py +34 -14
- {holmesgpt-0.14.2.dist-info → holmesgpt-0.14.4a0.dist-info}/METADATA +6 -8
- {holmesgpt-0.14.2.dist-info → holmesgpt-0.14.4a0.dist-info}/RECORD +66 -60
- holmes/core/tools_utils/data_types.py +0 -81
- holmes/plugins/toolsets/newrelic.py +0 -231
- {holmesgpt-0.14.2.dist-info → holmesgpt-0.14.4a0.dist-info}/LICENSE.txt +0 -0
- {holmesgpt-0.14.2.dist-info → holmesgpt-0.14.4a0.dist-info}/WHEEL +0 -0
- {holmesgpt-0.14.2.dist-info → holmesgpt-0.14.4a0.dist-info}/entry_points.txt +0 -0
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
import requests # type: ignore
|
|
2
|
-
import logging
|
|
3
|
-
from typing import Any, Optional, Dict
|
|
4
|
-
from holmes.core.tools import (
|
|
5
|
-
CallablePrerequisite,
|
|
6
|
-
Tool,
|
|
7
|
-
ToolParameter,
|
|
8
|
-
Toolset,
|
|
9
|
-
ToolsetTag,
|
|
10
|
-
)
|
|
11
|
-
from pydantic import BaseModel
|
|
12
|
-
from holmes.core.tools import StructuredToolResult, StructuredToolResultStatus
|
|
13
|
-
from holmes.plugins.toolsets.utils import get_param_or_raise, toolset_name_for_one_liner
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class BaseNewRelicTool(Tool):
|
|
17
|
-
toolset: "NewRelicToolset"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class GetLogs(BaseNewRelicTool):
|
|
21
|
-
def __init__(self, toolset: "NewRelicToolset"):
|
|
22
|
-
super().__init__(
|
|
23
|
-
name="newrelic_get_logs",
|
|
24
|
-
description="Retrieve logs from New Relic",
|
|
25
|
-
parameters={
|
|
26
|
-
"app": ToolParameter(
|
|
27
|
-
description="The application name to filter logs",
|
|
28
|
-
type="string",
|
|
29
|
-
required=True,
|
|
30
|
-
),
|
|
31
|
-
"since": ToolParameter(
|
|
32
|
-
description="Time range to fetch logs (e.g., '1 hour ago')",
|
|
33
|
-
type="string",
|
|
34
|
-
required=True,
|
|
35
|
-
),
|
|
36
|
-
},
|
|
37
|
-
toolset=toolset,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
def _invoke(
|
|
41
|
-
self, params: dict, user_approved: bool = False
|
|
42
|
-
) -> StructuredToolResult:
|
|
43
|
-
def success(msg: Any) -> StructuredToolResult:
|
|
44
|
-
return StructuredToolResult(
|
|
45
|
-
status=StructuredToolResultStatus.SUCCESS,
|
|
46
|
-
data=msg,
|
|
47
|
-
params=params,
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
def error(msg: str) -> StructuredToolResult:
|
|
51
|
-
return StructuredToolResult(
|
|
52
|
-
status=StructuredToolResultStatus.ERROR,
|
|
53
|
-
data=msg,
|
|
54
|
-
params=params,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
app = params.get("app")
|
|
58
|
-
since = params.get("since")
|
|
59
|
-
|
|
60
|
-
query = {
|
|
61
|
-
"query": f"""
|
|
62
|
-
{{
|
|
63
|
-
actor {{
|
|
64
|
-
account(id: {self.toolset.nr_account_id}) {{
|
|
65
|
-
nrql(query: \"SELECT * FROM Log WHERE app = '{app}' SINCE {since}\") {{
|
|
66
|
-
results
|
|
67
|
-
}}
|
|
68
|
-
}}
|
|
69
|
-
}}
|
|
70
|
-
}}
|
|
71
|
-
"""
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
url = "https://api.newrelic.com/graphql"
|
|
75
|
-
headers = {
|
|
76
|
-
"Content-Type": "application/json",
|
|
77
|
-
"Api-Key": self.toolset.nr_api_key,
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
try:
|
|
81
|
-
logging.info(f"Getting New Relic logs for app {app} since {since}")
|
|
82
|
-
response = requests.post(url, headers=headers, json=query) # type: ignore[arg-type]
|
|
83
|
-
|
|
84
|
-
if response.status_code == 200:
|
|
85
|
-
return success(response.json())
|
|
86
|
-
else:
|
|
87
|
-
return error(
|
|
88
|
-
f"Failed to fetch logs. Status code: {response.status_code}\n{response.text}"
|
|
89
|
-
)
|
|
90
|
-
except Exception as e:
|
|
91
|
-
logging.exception("Exception while fetching logs")
|
|
92
|
-
return error(f"Error while fetching logs: {str(e)}")
|
|
93
|
-
|
|
94
|
-
def get_parameterized_one_liner(self, params) -> str:
|
|
95
|
-
app = params.get("app", "")
|
|
96
|
-
since = params.get("since", "")
|
|
97
|
-
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Logs ({app} - {since})"
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
class GetTraces(BaseNewRelicTool):
|
|
101
|
-
def __init__(self, toolset: "NewRelicToolset"):
|
|
102
|
-
super().__init__(
|
|
103
|
-
name="newrelic_get_traces",
|
|
104
|
-
description="Retrieve traces from New Relic",
|
|
105
|
-
parameters={
|
|
106
|
-
"duration": ToolParameter(
|
|
107
|
-
description="Minimum trace duration in seconds",
|
|
108
|
-
type="number",
|
|
109
|
-
required=True,
|
|
110
|
-
),
|
|
111
|
-
"trace_id": ToolParameter(
|
|
112
|
-
description="Specific trace ID to fetch details (optional)",
|
|
113
|
-
type="string",
|
|
114
|
-
required=False,
|
|
115
|
-
),
|
|
116
|
-
},
|
|
117
|
-
toolset=toolset,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
def _invoke(
|
|
121
|
-
self, params: dict, user_approved: bool = False
|
|
122
|
-
) -> StructuredToolResult:
|
|
123
|
-
def success(msg: Any) -> StructuredToolResult:
|
|
124
|
-
return StructuredToolResult(
|
|
125
|
-
status=StructuredToolResultStatus.SUCCESS,
|
|
126
|
-
data=msg,
|
|
127
|
-
params=params,
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
def error(msg: str) -> StructuredToolResult:
|
|
131
|
-
return StructuredToolResult(
|
|
132
|
-
status=StructuredToolResultStatus.ERROR,
|
|
133
|
-
data=msg,
|
|
134
|
-
params=params,
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
duration = get_param_or_raise(params, "duration")
|
|
138
|
-
trace_id = params.get("trace_id")
|
|
139
|
-
|
|
140
|
-
if trace_id:
|
|
141
|
-
query_string = f"SELECT * FROM Span WHERE trace.id = '{trace_id}' and duration.ms > {duration * 1000} and span.kind != 'internal'"
|
|
142
|
-
else:
|
|
143
|
-
query_string = f"SELECT * FROM Span WHERE duration.ms > {duration * 1000} and span.kind != 'internal'"
|
|
144
|
-
|
|
145
|
-
query = {
|
|
146
|
-
"query": f"""
|
|
147
|
-
{{
|
|
148
|
-
actor {{
|
|
149
|
-
account(id: {self.toolset.nr_account_id}) {{
|
|
150
|
-
nrql(query: \"{query_string}\") {{
|
|
151
|
-
results
|
|
152
|
-
}}
|
|
153
|
-
}}
|
|
154
|
-
}}
|
|
155
|
-
}}
|
|
156
|
-
"""
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
url = "https://api.newrelic.com/graphql"
|
|
160
|
-
headers = {
|
|
161
|
-
"Content-Type": "application/json",
|
|
162
|
-
"Api-Key": self.toolset.nr_api_key,
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
try:
|
|
166
|
-
logging.info(f"Getting New Relic traces with duration > {duration}s")
|
|
167
|
-
response = requests.post(url, headers=headers, json=query) # type: ignore[arg-type]
|
|
168
|
-
|
|
169
|
-
if response.status_code == 200:
|
|
170
|
-
return success(response.json())
|
|
171
|
-
else:
|
|
172
|
-
return error(
|
|
173
|
-
f"Failed to fetch traces. Status code: {response.status_code}\n{response.text}"
|
|
174
|
-
)
|
|
175
|
-
except Exception as e:
|
|
176
|
-
logging.exception("Exception while fetching traces")
|
|
177
|
-
return error(f"Error while fetching traces: {str(e)}")
|
|
178
|
-
|
|
179
|
-
def get_parameterized_one_liner(self, params) -> str:
|
|
180
|
-
if "trace_id" in params and params["trace_id"]:
|
|
181
|
-
trace_id = params.get("trace_id", "")
|
|
182
|
-
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Trace Details ({trace_id})"
|
|
183
|
-
duration = params.get("duration", "")
|
|
184
|
-
return f"{toolset_name_for_one_liner(self.toolset.name)}: Get Traces (>{duration}s)"
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
class NewrelicConfig(BaseModel):
|
|
188
|
-
nr_api_key: Optional[str] = None
|
|
189
|
-
nr_account_id: Optional[str] = None
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
class NewRelicToolset(Toolset):
|
|
193
|
-
nr_api_key: Optional[str] = None
|
|
194
|
-
nr_account_id: Optional[str] = None
|
|
195
|
-
|
|
196
|
-
def __init__(self):
|
|
197
|
-
super().__init__(
|
|
198
|
-
name="newrelic",
|
|
199
|
-
description="Toolset for interacting with New Relic to fetch logs and traces",
|
|
200
|
-
docs_url="https://holmesgpt.dev/data-sources/builtin-toolsets/newrelic/",
|
|
201
|
-
icon_url="https://companieslogo.com/img/orig/NEWR-de5fcb2e.png?t=1720244493",
|
|
202
|
-
prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
|
|
203
|
-
tools=[
|
|
204
|
-
GetLogs(self),
|
|
205
|
-
GetTraces(self),
|
|
206
|
-
],
|
|
207
|
-
experimental=True,
|
|
208
|
-
tags=[ToolsetTag.CORE],
|
|
209
|
-
)
|
|
210
|
-
|
|
211
|
-
def prerequisites_callable(
|
|
212
|
-
self, config: dict[str, Any]
|
|
213
|
-
) -> tuple[bool, Optional[str]]:
|
|
214
|
-
if not config:
|
|
215
|
-
return False, "No configuration provided"
|
|
216
|
-
|
|
217
|
-
try:
|
|
218
|
-
nr_config = NewrelicConfig(**config)
|
|
219
|
-
self.nr_account_id = nr_config.nr_account_id
|
|
220
|
-
self.nr_api_key = nr_config.nr_api_key
|
|
221
|
-
|
|
222
|
-
if not self.nr_account_id or not self.nr_api_key:
|
|
223
|
-
return False, "New Relic account ID or API key is missing"
|
|
224
|
-
|
|
225
|
-
return True, None
|
|
226
|
-
except Exception as e:
|
|
227
|
-
logging.exception("Failed to set up New Relic toolset")
|
|
228
|
-
return False, str(e)
|
|
229
|
-
|
|
230
|
-
def get_example_config(self) -> Dict[str, Any]:
|
|
231
|
-
return {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|