holmesgpt 0.13.1__py3-none-any.whl → 0.13.3__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.

Files changed (76) hide show
  1. holmes/__init__.py +1 -1
  2. holmes/common/env_vars.py +7 -0
  3. holmes/config.py +3 -1
  4. holmes/core/conversations.py +0 -11
  5. holmes/core/investigation.py +0 -6
  6. holmes/core/llm.py +60 -1
  7. holmes/core/prompt.py +0 -2
  8. holmes/core/supabase_dal.py +2 -2
  9. holmes/core/todo_tasks_formatter.py +51 -0
  10. holmes/core/tool_calling_llm.py +166 -91
  11. holmes/core/tools.py +20 -4
  12. holmes/interactive.py +63 -2
  13. holmes/main.py +0 -1
  14. holmes/plugins/prompts/_general_instructions.jinja2 +3 -1
  15. holmes/plugins/prompts/investigation_procedure.jinja2 +3 -13
  16. holmes/plugins/toolsets/__init__.py +5 -1
  17. holmes/plugins/toolsets/argocd.yaml +1 -1
  18. holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +18 -6
  19. holmes/plugins/toolsets/aws.yaml +9 -5
  20. holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +3 -1
  21. holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +3 -1
  22. holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +3 -1
  23. holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +3 -1
  24. holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +3 -1
  25. holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +3 -1
  26. holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +3 -1
  27. holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +3 -1
  28. holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +3 -1
  29. holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +3 -1
  30. holmes/plugins/toolsets/bash/bash_toolset.py +31 -20
  31. holmes/plugins/toolsets/confluence.yaml +1 -1
  32. holmes/plugins/toolsets/coralogix/api.py +3 -1
  33. holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +4 -4
  34. holmes/plugins/toolsets/coralogix/utils.py +41 -14
  35. holmes/plugins/toolsets/datadog/datadog_api.py +45 -2
  36. holmes/plugins/toolsets/datadog/datadog_general_instructions.jinja2 +208 -0
  37. holmes/plugins/toolsets/datadog/datadog_logs_instructions.jinja2 +43 -0
  38. holmes/plugins/toolsets/datadog/datadog_metrics_instructions.jinja2 +12 -9
  39. holmes/plugins/toolsets/datadog/toolset_datadog_general.py +722 -0
  40. holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +17 -6
  41. holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +15 -7
  42. holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +6 -2
  43. holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +9 -3
  44. holmes/plugins/toolsets/docker.yaml +1 -1
  45. holmes/plugins/toolsets/git.py +15 -5
  46. holmes/plugins/toolsets/grafana/toolset_grafana.py +25 -4
  47. holmes/plugins/toolsets/grafana/toolset_grafana_loki.py +4 -4
  48. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.jinja2 +5 -3
  49. holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +299 -32
  50. holmes/plugins/toolsets/helm.yaml +1 -1
  51. holmes/plugins/toolsets/internet/internet.py +4 -2
  52. holmes/plugins/toolsets/internet/notion.py +4 -2
  53. holmes/plugins/toolsets/investigator/core_investigation.py +5 -17
  54. holmes/plugins/toolsets/investigator/investigator_instructions.jinja2 +1 -5
  55. holmes/plugins/toolsets/kafka.py +19 -7
  56. holmes/plugins/toolsets/kubernetes.yaml +5 -5
  57. holmes/plugins/toolsets/kubernetes_logs.py +4 -4
  58. holmes/plugins/toolsets/kubernetes_logs.yaml +1 -1
  59. holmes/plugins/toolsets/logging_utils/logging_api.py +15 -2
  60. holmes/plugins/toolsets/mcp/toolset_mcp.py +3 -1
  61. holmes/plugins/toolsets/newrelic.py +8 -4
  62. holmes/plugins/toolsets/opensearch/opensearch.py +13 -5
  63. holmes/plugins/toolsets/opensearch/opensearch_logs.py +4 -4
  64. holmes/plugins/toolsets/opensearch/opensearch_traces.py +9 -6
  65. holmes/plugins/toolsets/prometheus/prometheus.py +193 -82
  66. holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +7 -3
  67. holmes/plugins/toolsets/robusta/robusta.py +10 -4
  68. holmes/plugins/toolsets/runbook/runbook_fetcher.py +4 -2
  69. holmes/plugins/toolsets/servicenow/servicenow.py +9 -3
  70. holmes/plugins/toolsets/slab.yaml +1 -1
  71. {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3.dist-info}/METADATA +3 -2
  72. {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3.dist-info}/RECORD +75 -72
  73. holmes/core/todo_manager.py +0 -88
  74. {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3.dist-info}/LICENSE.txt +0 -0
  75. {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3.dist-info}/WHEEL +0 -0
  76. {holmesgpt-0.13.1.dist-info → holmesgpt-0.13.3.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://docs.robusta.dev/master/configuration/holmesgpt/toolsets/kubernetes.html#logs",
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://docs.robusta.dev/master/configuration/holmesgpt/toolsets/kubernetes.html#logs"
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
- description = "Fetch logs for a Kubernetes pod"
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(self, params: dict) -> StructuredToolResult:
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(self, params: Dict) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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.get("duration")
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(self, params: Any) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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://docs.robusta.dev/master/configuration/holmesgpt/toolsets/opensearch.html",
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://docs.robusta.dev/master/configuration/holmesgpt/toolsets/opensearch_logs.html",
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(self, params: Dict) -> StructuredToolResult:
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(self, params: Any) -> StructuredToolResult:
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.get("query"))
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://docs.robusta.dev/master/configuration/holmesgpt/toolsets/opensearch-traces.html",
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=[