holmesgpt 0.13.1__py3-none-any.whl → 0.13.3a0__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 +7 -0
- holmes/config.py +3 -1
- holmes/core/conversations.py +0 -11
- holmes/core/investigation.py +0 -6
- holmes/core/llm.py +60 -1
- holmes/core/prompt.py +0 -2
- holmes/core/supabase_dal.py +2 -2
- holmes/core/todo_tasks_formatter.py +51 -0
- holmes/core/tool_calling_llm.py +166 -91
- holmes/core/tools.py +20 -4
- holmes/interactive.py +63 -2
- holmes/main.py +0 -1
- holmes/plugins/prompts/_general_instructions.jinja2 +3 -1
- holmes/plugins/prompts/investigation_procedure.jinja2 +3 -13
- holmes/plugins/toolsets/__init__.py +5 -1
- holmes/plugins/toolsets/argocd.yaml +1 -1
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +18 -6
- holmes/plugins/toolsets/aws.yaml +9 -5
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +3 -1
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +3 -1
- holmes/plugins/toolsets/bash/bash_toolset.py +31 -20
- holmes/plugins/toolsets/confluence.yaml +1 -1
- holmes/plugins/toolsets/coralogix/api.py +3 -1
- holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +4 -4
- holmes/plugins/toolsets/coralogix/utils.py +41 -14
- holmes/plugins/toolsets/datadog/datadog_api.py +45 -2
- holmes/plugins/toolsets/datadog/datadog_general_instructions.jinja2 +208 -0
- holmes/plugins/toolsets/datadog/datadog_logs_instructions.jinja2 +43 -0
- holmes/plugins/toolsets/datadog/datadog_metrics_instructions.jinja2 +12 -9
- holmes/plugins/toolsets/datadog/toolset_datadog_general.py +722 -0
- holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +17 -6
- holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +15 -7
- holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +6 -2
- holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +9 -3
- holmes/plugins/toolsets/docker.yaml +1 -1
- holmes/plugins/toolsets/git.py +15 -5
- holmes/plugins/toolsets/grafana/toolset_grafana.py +25 -4
- holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +4 -4
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +5 -3
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +299 -32
- holmes/plugins/toolsets/helm.yaml +1 -1
- holmes/plugins/toolsets/internet/internet.py +4 -2
- holmes/plugins/toolsets/internet/notion.py +4 -2
- holmes/plugins/toolsets/investigator/core_investigation.py +5 -17
- holmes/plugins/toolsets/investigator/investigator_instructions.jinja2 +1 -5
- holmes/plugins/toolsets/kafka.py +19 -7
- holmes/plugins/toolsets/kubernetes.yaml +5 -5
- holmes/plugins/toolsets/kubernetes_logs.py +4 -4
- holmes/plugins/toolsets/kubernetes_logs.yaml +1 -1
- holmes/plugins/toolsets/logging_utils/logging_api.py +15 -2
- holmes/plugins/toolsets/mcp/toolset_mcp.py +3 -1
- holmes/plugins/toolsets/newrelic.py +8 -4
- holmes/plugins/toolsets/opensearch/opensearch.py +13 -5
- holmes/plugins/toolsets/opensearch/opensearch_logs.py +4 -4
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +9 -6
- holmes/plugins/toolsets/prometheus/prometheus.py +193 -82
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +7 -3
- holmes/plugins/toolsets/robusta/robusta.py +10 -4
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +4 -2
- holmes/plugins/toolsets/servicenow/servicenow.py +9 -3
- holmes/plugins/toolsets/slab.yaml +1 -1
- {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3a0.dist-info}/METADATA +3 -2
- {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3a0.dist-info}/RECORD +75 -72
- holmes/core/todo_manager.py +0 -88
- {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3a0.dist-info}/LICENSE.txt +0 -0
- {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3a0.dist-info}/WHEEL +0 -0
- {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3a0.dist-info}/entry_points.txt +0 -0
|
@@ -63,15 +63,15 @@ class KubernetesLogsToolset(BasePodLoggingToolset):
|
|
|
63
63
|
super().__init__(
|
|
64
64
|
name="kubernetes/logs",
|
|
65
65
|
description="Read Kubernetes pod logs using a unified API",
|
|
66
|
-
docs_url="https://
|
|
66
|
+
docs_url="https://holmesgpt.dev/data-sources/builtin-toolsets/kubernetes/",
|
|
67
67
|
icon_url="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPKA-U9m5BxYQDF1O7atMfj9EMMXEoGu4t0Q&s",
|
|
68
68
|
prerequisites=[prerequisite],
|
|
69
69
|
is_default=True,
|
|
70
|
-
tools=[
|
|
71
|
-
PodLoggingTool(self),
|
|
72
|
-
],
|
|
70
|
+
tools=[], # Initialize with empty tools first
|
|
73
71
|
tags=[ToolsetTag.CORE],
|
|
74
72
|
)
|
|
73
|
+
# Now that parent is initialized and self.name exists, create the tool
|
|
74
|
+
self.tools = [PodLoggingTool(self)]
|
|
75
75
|
enabled, disabled_reason = self.health_check()
|
|
76
76
|
prerequisite.enabled = enabled
|
|
77
77
|
prerequisite.disabled_reason = disabled_reason
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
toolsets:
|
|
2
2
|
kubernetes/logs:
|
|
3
3
|
description: "Read pod logs"
|
|
4
|
-
docs_url: "https://
|
|
4
|
+
docs_url: "https://holmesgpt.dev/data-sources/builtin-toolsets/kubernetes/"
|
|
5
5
|
icon_url: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPKA-U9m5BxYQDF1O7atMfj9EMMXEoGu4t0Q&s"
|
|
6
6
|
tags:
|
|
7
7
|
- core
|
|
@@ -18,6 +18,7 @@ from holmes.plugins.toolsets.utils import get_param_or_raise
|
|
|
18
18
|
DEFAULT_LOG_LIMIT = 100
|
|
19
19
|
SECONDS_PER_DAY = 24 * 60 * 60
|
|
20
20
|
DEFAULT_TIME_SPAN_SECONDS = 7 * SECONDS_PER_DAY # 1 week in seconds
|
|
21
|
+
DEFAULT_GRAPH_TIME_SPAN_SECONDS = 1 * SECONDS_PER_DAY # 1 day in seconds
|
|
21
22
|
|
|
22
23
|
POD_LOGGING_TOOL_NAME = "fetch_pod_logs"
|
|
23
24
|
|
|
@@ -27,6 +28,9 @@ class LoggingCapability(str, Enum):
|
|
|
27
28
|
|
|
28
29
|
REGEX_FILTER = "regex_filter" # If not supported, falls back to substring matching
|
|
29
30
|
EXCLUDE_FILTER = "exclude_filter" # If not supported, parameter is not shown at all
|
|
31
|
+
HISTORICAL_DATA = (
|
|
32
|
+
"historical_data" # Can fetch logs for pods no longer in the cluster
|
|
33
|
+
)
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
class LoggingConfig(BaseModel):
|
|
@@ -78,9 +82,16 @@ class PodLoggingTool(Tool):
|
|
|
78
82
|
parameters = self._get_tool_parameters(toolset)
|
|
79
83
|
|
|
80
84
|
# Build description based on capabilities
|
|
81
|
-
|
|
85
|
+
# Include the toolset name in the description
|
|
86
|
+
toolset_name = toolset.name if toolset.name else "logging backend"
|
|
87
|
+
description = f"Fetch logs for a Kubernetes pod from {toolset_name}"
|
|
82
88
|
capabilities = toolset.supported_capabilities
|
|
83
89
|
|
|
90
|
+
if LoggingCapability.HISTORICAL_DATA in capabilities:
|
|
91
|
+
description += (
|
|
92
|
+
" (including historical data for pods no longer in the cluster)"
|
|
93
|
+
)
|
|
94
|
+
|
|
84
95
|
if (
|
|
85
96
|
LoggingCapability.REGEX_FILTER in capabilities
|
|
86
97
|
and LoggingCapability.EXCLUDE_FILTER in capabilities
|
|
@@ -164,7 +175,9 @@ If you hit the log limit and see lots of repetitive INFO logs, use exclude_filte
|
|
|
164
175
|
|
|
165
176
|
return params
|
|
166
177
|
|
|
167
|
-
def _invoke(
|
|
178
|
+
def _invoke(
|
|
179
|
+
self, params: dict, user_approved: bool = False
|
|
180
|
+
) -> StructuredToolResult:
|
|
168
181
|
structured_params = FetchPodLogsParams(
|
|
169
182
|
namespace=get_param_or_raise(params, "namespace"),
|
|
170
183
|
pod_name=get_param_or_raise(params, "pod_name"),
|
|
@@ -24,7 +24,9 @@ class RemoteMCPTool(Tool):
|
|
|
24
24
|
url: str
|
|
25
25
|
headers: Optional[Dict[str, str]] = None
|
|
26
26
|
|
|
27
|
-
def _invoke(
|
|
27
|
+
def _invoke(
|
|
28
|
+
self, params: dict, user_approved: bool = False
|
|
29
|
+
) -> StructuredToolResult:
|
|
28
30
|
try:
|
|
29
31
|
return asyncio.run(self._invoke_async(params))
|
|
30
32
|
except Exception as e:
|
|
@@ -10,7 +10,7 @@ from holmes.core.tools import (
|
|
|
10
10
|
)
|
|
11
11
|
from pydantic import BaseModel
|
|
12
12
|
from holmes.core.tools import StructuredToolResult, ToolResultStatus
|
|
13
|
-
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
13
|
+
from holmes.plugins.toolsets.utils import get_param_or_raise, toolset_name_for_one_liner
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class BaseNewRelicTool(Tool):
|
|
@@ -37,7 +37,9 @@ class GetLogs(BaseNewRelicTool):
|
|
|
37
37
|
toolset=toolset,
|
|
38
38
|
)
|
|
39
39
|
|
|
40
|
-
def _invoke(
|
|
40
|
+
def _invoke(
|
|
41
|
+
self, params: dict, user_approved: bool = False
|
|
42
|
+
) -> StructuredToolResult:
|
|
41
43
|
def success(msg: Any) -> StructuredToolResult:
|
|
42
44
|
return StructuredToolResult(
|
|
43
45
|
status=ToolResultStatus.SUCCESS,
|
|
@@ -115,7 +117,9 @@ class GetTraces(BaseNewRelicTool):
|
|
|
115
117
|
toolset=toolset,
|
|
116
118
|
)
|
|
117
119
|
|
|
118
|
-
def _invoke(
|
|
120
|
+
def _invoke(
|
|
121
|
+
self, params: dict, user_approved: bool = False
|
|
122
|
+
) -> StructuredToolResult:
|
|
119
123
|
def success(msg: Any) -> StructuredToolResult:
|
|
120
124
|
return StructuredToolResult(
|
|
121
125
|
status=ToolResultStatus.SUCCESS,
|
|
@@ -130,7 +134,7 @@ class GetTraces(BaseNewRelicTool):
|
|
|
130
134
|
params=params,
|
|
131
135
|
)
|
|
132
136
|
|
|
133
|
-
duration = params
|
|
137
|
+
duration = get_param_or_raise(params, "duration")
|
|
134
138
|
trace_id = params.get("trace_id")
|
|
135
139
|
|
|
136
140
|
if trace_id:
|
|
@@ -93,7 +93,9 @@ class ListShards(BaseOpenSearchTool):
|
|
|
93
93
|
toolset=toolset,
|
|
94
94
|
)
|
|
95
95
|
|
|
96
|
-
def _invoke(
|
|
96
|
+
def _invoke(
|
|
97
|
+
self, params: dict, user_approved: bool = False
|
|
98
|
+
) -> StructuredToolResult:
|
|
97
99
|
client = get_client(self.toolset.clients, host=params.get("host", ""))
|
|
98
100
|
shards = client.client.cat.shards()
|
|
99
101
|
return StructuredToolResult(
|
|
@@ -122,7 +124,9 @@ class GetClusterSettings(BaseOpenSearchTool):
|
|
|
122
124
|
toolset=toolset,
|
|
123
125
|
)
|
|
124
126
|
|
|
125
|
-
def _invoke(
|
|
127
|
+
def _invoke(
|
|
128
|
+
self, params: dict, user_approved: bool = False
|
|
129
|
+
) -> StructuredToolResult:
|
|
126
130
|
client = get_client(self.toolset.clients, host=params.get("host"))
|
|
127
131
|
response = client.client.cluster.get_settings(
|
|
128
132
|
include_defaults=True, flat_settings=True
|
|
@@ -153,7 +157,9 @@ class GetClusterHealth(BaseOpenSearchTool):
|
|
|
153
157
|
toolset=toolset,
|
|
154
158
|
)
|
|
155
159
|
|
|
156
|
-
def _invoke(
|
|
160
|
+
def _invoke(
|
|
161
|
+
self, params: dict, user_approved: bool = False
|
|
162
|
+
) -> StructuredToolResult:
|
|
157
163
|
client = get_client(self.toolset.clients, host=params.get("host", ""))
|
|
158
164
|
health = client.client.cluster.health()
|
|
159
165
|
return StructuredToolResult(
|
|
@@ -176,7 +182,9 @@ class ListOpenSearchHosts(BaseOpenSearchTool):
|
|
|
176
182
|
toolset=toolset,
|
|
177
183
|
)
|
|
178
184
|
|
|
179
|
-
def _invoke(
|
|
185
|
+
def _invoke(
|
|
186
|
+
self, params: dict, user_approved: bool = False
|
|
187
|
+
) -> StructuredToolResult:
|
|
180
188
|
hosts = [host for client in self.toolset.clients for host in client.hosts]
|
|
181
189
|
return StructuredToolResult(
|
|
182
190
|
status=ToolResultStatus.SUCCESS,
|
|
@@ -197,7 +205,7 @@ class OpenSearchToolset(Toolset):
|
|
|
197
205
|
name="opensearch/status",
|
|
198
206
|
enabled=False,
|
|
199
207
|
description="Provide cluster metadata information like health, shards, settings.",
|
|
200
|
-
docs_url="https://
|
|
208
|
+
docs_url="https://holmesgpt.dev/data-sources/builtin-toolsets/opensearch-status/",
|
|
201
209
|
icon_url="https://opensearch.org/assets/brand/PNG/Mark/opensearch_mark_default.png",
|
|
202
210
|
prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
|
|
203
211
|
tools=[
|
|
@@ -42,16 +42,16 @@ class OpenSearchLogsToolset(BasePodLoggingToolset):
|
|
|
42
42
|
super().__init__(
|
|
43
43
|
name="opensearch/logs",
|
|
44
44
|
description="OpenSearch integration to fetch logs",
|
|
45
|
-
docs_url="https://
|
|
45
|
+
docs_url="https://holmesgpt.dev/data-sources/builtin-toolsets/opensearch-logs/",
|
|
46
46
|
icon_url="https://opensearch.org/wp-content/uploads/2025/01/opensearch_mark_default.png",
|
|
47
47
|
prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
|
|
48
|
-
tools=[
|
|
49
|
-
PodLoggingTool(self),
|
|
50
|
-
],
|
|
48
|
+
tools=[], # Initialize with empty tools first
|
|
51
49
|
tags=[
|
|
52
50
|
ToolsetTag.CORE,
|
|
53
51
|
],
|
|
54
52
|
)
|
|
53
|
+
# Now that parent is initialized and self.name exists, create the tool
|
|
54
|
+
self.tools = [PodLoggingTool(self)]
|
|
55
55
|
|
|
56
56
|
def get_example_config(self) -> Dict[str, Any]:
|
|
57
57
|
example_config = OpenSearchLoggingConfig(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import logging
|
|
3
3
|
|
|
4
|
-
from typing import Any, Dict
|
|
5
4
|
|
|
6
5
|
import requests # type: ignore
|
|
7
6
|
from cachetools import TTLCache # type: ignore
|
|
@@ -20,7 +19,7 @@ from holmes.plugins.toolsets.opensearch.opensearch_utils import (
|
|
|
20
19
|
get_search_url,
|
|
21
20
|
)
|
|
22
21
|
from holmes.core.tools import StructuredToolResult, ToolResultStatus
|
|
23
|
-
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
22
|
+
from holmes.plugins.toolsets.utils import get_param_or_raise, toolset_name_for_one_liner
|
|
24
23
|
|
|
25
24
|
TRACES_FIELDS_CACHE_KEY = "cached_traces_fields"
|
|
26
25
|
|
|
@@ -35,7 +34,9 @@ class GetTracesFields(Tool):
|
|
|
35
34
|
self._toolset = toolset
|
|
36
35
|
self._cache = None
|
|
37
36
|
|
|
38
|
-
def _invoke(
|
|
37
|
+
def _invoke(
|
|
38
|
+
self, params: dict, user_approved: bool = False
|
|
39
|
+
) -> StructuredToolResult:
|
|
39
40
|
try:
|
|
40
41
|
if not self._cache and self._toolset.opensearch_config.fields_ttl_seconds:
|
|
41
42
|
self._cache = TTLCache(
|
|
@@ -128,10 +129,12 @@ class TracesSearchQuery(Tool):
|
|
|
128
129
|
self._toolset = toolset
|
|
129
130
|
self._cache = None
|
|
130
131
|
|
|
131
|
-
def _invoke(
|
|
132
|
+
def _invoke(
|
|
133
|
+
self, params: dict, user_approved: bool = False
|
|
134
|
+
) -> StructuredToolResult:
|
|
132
135
|
err_msg = ""
|
|
133
136
|
try:
|
|
134
|
-
body = json.loads(params
|
|
137
|
+
body = json.loads(get_param_or_raise(params, "query"))
|
|
135
138
|
full_query = body
|
|
136
139
|
full_query["size"] = int(
|
|
137
140
|
os.environ.get("OPENSEARCH_TRACES_SEARCH_SIZE", "5000")
|
|
@@ -196,7 +199,7 @@ class OpenSearchTracesToolset(BaseOpenSearchToolset):
|
|
|
196
199
|
super().__init__(
|
|
197
200
|
name="opensearch/traces",
|
|
198
201
|
description="OpenSearch integration to fetch traces",
|
|
199
|
-
docs_url="https://
|
|
202
|
+
docs_url="https://holmesgpt.dev/data-sources/builtin-toolsets/opensearch-status/",
|
|
200
203
|
icon_url="https://opensearch.org/assets/brand/PNG/Mark/opensearch_mark_default.png",
|
|
201
204
|
prerequisites=[CallablePrerequisite(callable=self.prerequisites_callable)],
|
|
202
205
|
tools=[
|