holmesgpt 0.16.2a0__py3-none-any.whl → 0.18.4__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.
- holmes/__init__.py +3 -5
- holmes/clients/robusta_client.py +4 -3
- holmes/common/env_vars.py +18 -2
- holmes/common/openshift.py +1 -1
- holmes/config.py +11 -6
- holmes/core/conversations.py +30 -13
- holmes/core/investigation.py +21 -25
- holmes/core/investigation_structured_output.py +3 -3
- holmes/core/issue.py +1 -1
- holmes/core/llm.py +50 -31
- holmes/core/models.py +19 -17
- holmes/core/openai_formatting.py +1 -1
- holmes/core/prompt.py +47 -2
- holmes/core/runbooks.py +1 -0
- holmes/core/safeguards.py +4 -2
- holmes/core/supabase_dal.py +4 -2
- holmes/core/tool_calling_llm.py +102 -141
- holmes/core/tools.py +19 -28
- holmes/core/tools_utils/token_counting.py +9 -2
- holmes/core/tools_utils/tool_context_window_limiter.py +13 -30
- holmes/core/tools_utils/tool_executor.py +0 -18
- holmes/core/tools_utils/toolset_utils.py +1 -0
- holmes/core/toolset_manager.py +37 -2
- holmes/core/tracing.py +13 -2
- holmes/core/transformers/__init__.py +1 -1
- holmes/core/transformers/base.py +1 -0
- holmes/core/transformers/llm_summarize.py +3 -2
- holmes/core/transformers/registry.py +2 -1
- holmes/core/transformers/transformer.py +1 -0
- holmes/core/truncation/compaction.py +37 -2
- holmes/core/truncation/input_context_window_limiter.py +3 -2
- holmes/interactive.py +52 -8
- holmes/main.py +17 -37
- holmes/plugins/interfaces.py +2 -1
- holmes/plugins/prompts/__init__.py +2 -1
- holmes/plugins/prompts/_fetch_logs.jinja2 +5 -5
- holmes/plugins/prompts/_runbook_instructions.jinja2 +2 -1
- holmes/plugins/prompts/base_user_prompt.jinja2 +7 -0
- holmes/plugins/prompts/conversation_history_compaction.jinja2 +2 -1
- holmes/plugins/prompts/generic_ask.jinja2 +0 -2
- holmes/plugins/prompts/generic_ask_conversation.jinja2 +0 -2
- holmes/plugins/prompts/generic_ask_for_issue_conversation.jinja2 +0 -2
- holmes/plugins/prompts/generic_investigation.jinja2 +0 -2
- holmes/plugins/prompts/investigation_procedure.jinja2 +2 -1
- holmes/plugins/prompts/kubernetes_workload_ask.jinja2 +0 -2
- holmes/plugins/prompts/kubernetes_workload_chat.jinja2 +0 -2
- holmes/plugins/runbooks/__init__.py +32 -3
- holmes/plugins/sources/github/__init__.py +4 -2
- holmes/plugins/sources/prometheus/models.py +1 -0
- holmes/plugins/toolsets/__init__.py +30 -26
- holmes/plugins/toolsets/atlas_mongodb/mongodb_atlas.py +13 -12
- holmes/plugins/toolsets/azure_sql/apis/alert_monitoring_api.py +3 -2
- holmes/plugins/toolsets/azure_sql/apis/azure_sql_api.py +2 -1
- holmes/plugins/toolsets/azure_sql/apis/connection_failure_api.py +3 -2
- holmes/plugins/toolsets/azure_sql/apis/connection_monitoring_api.py +3 -1
- holmes/plugins/toolsets/azure_sql/apis/storage_analysis_api.py +3 -1
- holmes/plugins/toolsets/azure_sql/azure_sql_toolset.py +12 -12
- holmes/plugins/toolsets/azure_sql/tools/analyze_connection_failures.py +7 -7
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_connections.py +7 -7
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_health_status.py +3 -5
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_performance.py +3 -3
- holmes/plugins/toolsets/azure_sql/tools/analyze_database_storage.py +7 -7
- holmes/plugins/toolsets/azure_sql/tools/get_active_alerts.py +6 -8
- holmes/plugins/toolsets/azure_sql/tools/get_slow_queries.py +3 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_cpu_queries.py +3 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_data_io_queries.py +3 -3
- holmes/plugins/toolsets/azure_sql/tools/get_top_log_io_queries.py +3 -3
- holmes/plugins/toolsets/azure_sql/utils.py +0 -32
- holmes/plugins/toolsets/bash/argocd/__init__.py +3 -3
- holmes/plugins/toolsets/bash/aws/__init__.py +4 -4
- holmes/plugins/toolsets/bash/azure/__init__.py +4 -4
- holmes/plugins/toolsets/bash/bash_toolset.py +2 -3
- holmes/plugins/toolsets/bash/common/bash.py +19 -9
- holmes/plugins/toolsets/bash/common/bash_command.py +1 -1
- holmes/plugins/toolsets/bash/common/stringify.py +1 -1
- holmes/plugins/toolsets/bash/kubectl/__init__.py +2 -1
- holmes/plugins/toolsets/bash/kubectl/constants.py +0 -1
- holmes/plugins/toolsets/bash/kubectl/kubectl_get.py +3 -4
- holmes/plugins/toolsets/bash/parse_command.py +12 -13
- holmes/plugins/toolsets/connectivity_check.py +124 -0
- holmes/plugins/toolsets/coralogix/api.py +132 -119
- holmes/plugins/toolsets/coralogix/coralogix.jinja2 +14 -0
- holmes/plugins/toolsets/coralogix/toolset_coralogix.py +219 -0
- holmes/plugins/toolsets/coralogix/utils.py +15 -79
- holmes/plugins/toolsets/datadog/datadog_api.py +36 -3
- holmes/plugins/toolsets/datadog/datadog_logs_instructions.jinja2 +34 -1
- holmes/plugins/toolsets/datadog/datadog_metrics_instructions.jinja2 +3 -3
- holmes/plugins/toolsets/datadog/datadog_models.py +59 -0
- holmes/plugins/toolsets/datadog/datadog_url_utils.py +213 -0
- holmes/plugins/toolsets/datadog/instructions_datadog_traces.jinja2 +165 -28
- holmes/plugins/toolsets/datadog/toolset_datadog_general.py +71 -28
- holmes/plugins/toolsets/datadog/toolset_datadog_logs.py +224 -375
- holmes/plugins/toolsets/datadog/toolset_datadog_metrics.py +67 -36
- holmes/plugins/toolsets/datadog/toolset_datadog_traces.py +360 -343
- holmes/plugins/toolsets/elasticsearch/__init__.py +6 -0
- holmes/plugins/toolsets/elasticsearch/elasticsearch.py +834 -0
- holmes/plugins/toolsets/git.py +7 -8
- holmes/plugins/toolsets/grafana/base_grafana_toolset.py +16 -4
- holmes/plugins/toolsets/grafana/common.py +2 -30
- holmes/plugins/toolsets/grafana/grafana_tempo_api.py +2 -1
- holmes/plugins/toolsets/grafana/loki/instructions.jinja2 +18 -2
- holmes/plugins/toolsets/grafana/loki/toolset_grafana_loki.py +92 -18
- holmes/plugins/toolsets/grafana/loki_api.py +4 -0
- holmes/plugins/toolsets/grafana/toolset_grafana.py +109 -25
- holmes/plugins/toolsets/grafana/toolset_grafana_dashboard.jinja2 +22 -0
- holmes/plugins/toolsets/grafana/toolset_grafana_tempo.py +201 -33
- holmes/plugins/toolsets/grafana/trace_parser.py +3 -2
- holmes/plugins/toolsets/internet/internet.py +10 -10
- holmes/plugins/toolsets/internet/notion.py +5 -6
- holmes/plugins/toolsets/investigator/core_investigation.py +3 -3
- holmes/plugins/toolsets/investigator/model.py +3 -1
- holmes/plugins/toolsets/json_filter_mixin.py +134 -0
- holmes/plugins/toolsets/kafka.py +12 -7
- holmes/plugins/toolsets/kubernetes.yaml +260 -30
- holmes/plugins/toolsets/kubernetes_logs.py +3 -3
- holmes/plugins/toolsets/logging_utils/logging_api.py +16 -6
- holmes/plugins/toolsets/mcp/toolset_mcp.py +88 -60
- holmes/plugins/toolsets/newrelic/new_relic_api.py +41 -1
- holmes/plugins/toolsets/newrelic/newrelic.jinja2 +24 -0
- holmes/plugins/toolsets/newrelic/newrelic.py +212 -55
- holmes/plugins/toolsets/prometheus/prometheus.py +358 -102
- holmes/plugins/toolsets/prometheus/prometheus_instructions.jinja2 +11 -3
- holmes/plugins/toolsets/rabbitmq/api.py +23 -4
- holmes/plugins/toolsets/rabbitmq/toolset_rabbitmq.py +5 -5
- holmes/plugins/toolsets/robusta/robusta.py +5 -5
- holmes/plugins/toolsets/runbook/runbook_fetcher.py +25 -6
- holmes/plugins/toolsets/servicenow_tables/servicenow_tables.py +1 -1
- holmes/plugins/toolsets/utils.py +1 -1
- holmes/utils/config_utils.py +1 -1
- holmes/utils/connection_utils.py +31 -0
- holmes/utils/console/result.py +10 -0
- holmes/utils/file_utils.py +2 -1
- holmes/utils/global_instructions.py +10 -26
- holmes/utils/holmes_status.py +4 -3
- holmes/utils/log.py +15 -0
- holmes/utils/markdown_utils.py +2 -3
- holmes/utils/memory_limit.py +58 -0
- holmes/utils/sentry_helper.py +23 -0
- holmes/utils/stream.py +12 -5
- holmes/utils/tags.py +4 -3
- holmes/version.py +3 -1
- {holmesgpt-0.16.2a0.dist-info → holmesgpt-0.18.4.dist-info}/METADATA +12 -10
- holmesgpt-0.18.4.dist-info/RECORD +258 -0
- holmes/plugins/toolsets/aws.yaml +0 -80
- holmes/plugins/toolsets/coralogix/toolset_coralogix_logs.py +0 -114
- holmes/plugins/toolsets/datadog/datadog_traces_formatter.py +0 -310
- holmes/plugins/toolsets/datadog/toolset_datadog_rds.py +0 -736
- holmes/plugins/toolsets/grafana/grafana_api.py +0 -64
- holmes/plugins/toolsets/opensearch/__init__.py +0 -0
- holmes/plugins/toolsets/opensearch/opensearch.py +0 -250
- holmes/plugins/toolsets/opensearch/opensearch_logs.py +0 -161
- holmes/plugins/toolsets/opensearch/opensearch_traces.py +0 -215
- holmes/plugins/toolsets/opensearch/opensearch_traces_instructions.jinja2 +0 -12
- holmes/plugins/toolsets/opensearch/opensearch_utils.py +0 -166
- holmes/utils/keygen_utils.py +0 -6
- holmesgpt-0.16.2a0.dist-info/RECORD +0 -258
- holmes/plugins/toolsets/{opensearch → elasticsearch}/opensearch_ppl_query_docs.jinja2 +0 -0
- holmes/plugins/toolsets/{opensearch → elasticsearch}/opensearch_query_assist.py +2 -2
- /holmes/plugins/toolsets/{opensearch → elasticsearch}/opensearch_query_assist_instructions.jinja2 +0 -0
- {holmesgpt-0.16.2a0.dist-info → holmesgpt-0.18.4.dist-info}/LICENSE +0 -0
- {holmesgpt-0.16.2a0.dist-info → holmesgpt-0.18.4.dist-info}/WHEEL +0 -0
- {holmesgpt-0.16.2a0.dist-info → holmesgpt-0.18.4.dist-info}/entry_points.txt +0 -0
|
@@ -5,34 +5,37 @@ import logging
|
|
|
5
5
|
import os
|
|
6
6
|
import re
|
|
7
7
|
from typing import Any, Dict, Optional, Tuple
|
|
8
|
-
from urllib.parse import urlparse
|
|
8
|
+
from urllib.parse import urlencode, urlparse
|
|
9
9
|
|
|
10
10
|
from holmes.core.tools import (
|
|
11
11
|
CallablePrerequisite,
|
|
12
|
+
StructuredToolResult,
|
|
13
|
+
StructuredToolResultStatus,
|
|
12
14
|
Tool,
|
|
13
15
|
ToolInvokeContext,
|
|
14
16
|
ToolParameter,
|
|
15
17
|
Toolset,
|
|
16
|
-
StructuredToolResult,
|
|
17
|
-
StructuredToolResultStatus,
|
|
18
18
|
ToolsetTag,
|
|
19
19
|
)
|
|
20
20
|
from holmes.plugins.toolsets.consts import TOOLSET_CONFIG_MISSING_ERROR
|
|
21
21
|
from holmes.plugins.toolsets.datadog.datadog_api import (
|
|
22
|
-
|
|
22
|
+
MAX_RETRY_COUNT_ON_RATE_LIMIT,
|
|
23
23
|
DataDogRequestError,
|
|
24
|
+
enhance_error_message,
|
|
24
25
|
execute_datadog_http_request,
|
|
26
|
+
fetch_openapi_spec,
|
|
25
27
|
get_headers,
|
|
26
|
-
MAX_RETRY_COUNT_ON_RATE_LIMIT,
|
|
27
28
|
preprocess_time_fields,
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
)
|
|
30
|
+
from holmes.plugins.toolsets.datadog.datadog_models import (
|
|
31
|
+
MAX_RESPONSE_SIZE,
|
|
32
|
+
DatadogGeneralConfig,
|
|
33
|
+
)
|
|
34
|
+
from holmes.plugins.toolsets.datadog.datadog_url_utils import (
|
|
35
|
+
generate_datadog_general_url,
|
|
30
36
|
)
|
|
31
37
|
from holmes.plugins.toolsets.utils import toolset_name_for_one_liner
|
|
32
38
|
|
|
33
|
-
# Maximum response size in bytes (10MB)
|
|
34
|
-
MAX_RESPONSE_SIZE = 10 * 1024 * 1024
|
|
35
|
-
|
|
36
39
|
# Whitelisted API endpoint patterns with optional hints
|
|
37
40
|
# Format: (pattern, hint) - hint is empty string if no special instructions
|
|
38
41
|
WHITELISTED_ENDPOINTS = [
|
|
@@ -192,15 +195,6 @@ WHITELISTED_POST_ENDPOINTS = [
|
|
|
192
195
|
]
|
|
193
196
|
|
|
194
197
|
|
|
195
|
-
class DatadogGeneralConfig(DatadogBaseConfig):
|
|
196
|
-
"""Configuration for general-purpose Datadog toolset."""
|
|
197
|
-
|
|
198
|
-
max_response_size: int = MAX_RESPONSE_SIZE
|
|
199
|
-
allow_custom_endpoints: bool = (
|
|
200
|
-
False # If True, allows endpoints not in whitelist (still filtered for safety)
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
|
|
204
198
|
class DatadogGeneralToolset(Toolset):
|
|
205
199
|
"""General-purpose Datadog API toolset for read-only operations not covered by specialized toolsets."""
|
|
206
200
|
|
|
@@ -402,20 +396,22 @@ class DatadogAPIGet(BaseDatadogGeneralTool):
|
|
|
402
396
|
|
|
403
397
|
def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
|
|
404
398
|
"""Execute the GET request."""
|
|
399
|
+
params_return = params.copy()
|
|
400
|
+
params_return["query_params"] = json.dumps(
|
|
401
|
+
params.get("query_params", {}), indent=2
|
|
402
|
+
)
|
|
405
403
|
logging.info("=" * 60)
|
|
406
404
|
logging.info("DatadogAPIGet Tool Invocation:")
|
|
407
405
|
logging.info(f" Description: {params.get('description', 'No description')}")
|
|
408
406
|
logging.info(f" Endpoint: {params.get('endpoint', '')}")
|
|
409
|
-
logging.info(
|
|
410
|
-
f" Query Params: {json.dumps(params.get('query_params', {}), indent=2)}"
|
|
411
|
-
)
|
|
407
|
+
logging.info(f" Query Params: {params_return['query_params']}")
|
|
412
408
|
logging.info("=" * 60)
|
|
413
409
|
|
|
414
410
|
if not self.toolset.dd_config:
|
|
415
411
|
return StructuredToolResult(
|
|
416
412
|
status=StructuredToolResultStatus.ERROR,
|
|
417
413
|
error=TOOLSET_CONFIG_MISSING_ERROR,
|
|
418
|
-
params=
|
|
414
|
+
params=params_return,
|
|
419
415
|
)
|
|
420
416
|
|
|
421
417
|
endpoint = params.get("endpoint", "")
|
|
@@ -432,7 +428,7 @@ class DatadogAPIGet(BaseDatadogGeneralTool):
|
|
|
432
428
|
return StructuredToolResult(
|
|
433
429
|
status=StructuredToolResultStatus.ERROR,
|
|
434
430
|
error=f"Endpoint validation failed: {error_msg}",
|
|
435
|
-
params=
|
|
431
|
+
params=params_return,
|
|
436
432
|
)
|
|
437
433
|
|
|
438
434
|
url = None
|
|
@@ -466,13 +462,20 @@ class DatadogAPIGet(BaseDatadogGeneralTool):
|
|
|
466
462
|
return StructuredToolResult(
|
|
467
463
|
status=StructuredToolResultStatus.ERROR,
|
|
468
464
|
error=f"Response too large (>{self.toolset.dd_config.max_response_size} bytes)",
|
|
469
|
-
params=
|
|
465
|
+
params=params_return,
|
|
470
466
|
)
|
|
471
467
|
|
|
468
|
+
web_url = generate_datadog_general_url(
|
|
469
|
+
self.toolset.dd_config,
|
|
470
|
+
endpoint,
|
|
471
|
+
query_params,
|
|
472
|
+
)
|
|
473
|
+
|
|
472
474
|
return StructuredToolResult(
|
|
473
475
|
status=StructuredToolResultStatus.SUCCESS,
|
|
474
476
|
data=response_str,
|
|
475
|
-
params=
|
|
477
|
+
params=params_return,
|
|
478
|
+
url=web_url,
|
|
476
479
|
)
|
|
477
480
|
|
|
478
481
|
except DataDogRequestError as e:
|
|
@@ -497,7 +500,7 @@ class DatadogAPIGet(BaseDatadogGeneralTool):
|
|
|
497
500
|
return StructuredToolResult(
|
|
498
501
|
status=StructuredToolResultStatus.ERROR,
|
|
499
502
|
error=error_msg,
|
|
500
|
-
params=
|
|
503
|
+
params=params_return,
|
|
501
504
|
invocation=json.dumps({"url": url, "params": query_params})
|
|
502
505
|
if url
|
|
503
506
|
else None,
|
|
@@ -508,7 +511,7 @@ class DatadogAPIGet(BaseDatadogGeneralTool):
|
|
|
508
511
|
return StructuredToolResult(
|
|
509
512
|
status=StructuredToolResultStatus.ERROR,
|
|
510
513
|
error=f"Unexpected error: {str(e)}",
|
|
511
|
-
params=
|
|
514
|
+
params=params_return,
|
|
512
515
|
)
|
|
513
516
|
|
|
514
517
|
|
|
@@ -566,6 +569,31 @@ class DatadogAPIPostSearch(BaseDatadogGeneralTool):
|
|
|
566
569
|
description = params.get("description", "Search")
|
|
567
570
|
return f"{toolset_name_for_one_liner(self.toolset.name)}: {description}"
|
|
568
571
|
|
|
572
|
+
def _body_to_query_params(self, body: dict) -> Optional[Dict[str, Any]]:
|
|
573
|
+
body_query_params = {}
|
|
574
|
+
if not isinstance(body, dict):
|
|
575
|
+
return None
|
|
576
|
+
if "filter" not in body:
|
|
577
|
+
return None
|
|
578
|
+
filter_data = body["filter"]
|
|
579
|
+
if "from" in filter_data:
|
|
580
|
+
try:
|
|
581
|
+
body_query_params["from"] = int(filter_data["from"]) // 1000
|
|
582
|
+
except (ValueError, TypeError):
|
|
583
|
+
pass
|
|
584
|
+
if "to" in filter_data:
|
|
585
|
+
try:
|
|
586
|
+
body_query_params["to"] = int(filter_data["to"]) // 1000
|
|
587
|
+
except (ValueError, TypeError):
|
|
588
|
+
pass
|
|
589
|
+
if "query" in filter_data:
|
|
590
|
+
body_query_params["query"] = filter_data["query"]
|
|
591
|
+
|
|
592
|
+
if not body_query_params:
|
|
593
|
+
return None
|
|
594
|
+
|
|
595
|
+
return body_query_params
|
|
596
|
+
|
|
569
597
|
def _invoke(self, params: dict, context: ToolInvokeContext) -> StructuredToolResult:
|
|
570
598
|
"""Execute the POST search request."""
|
|
571
599
|
logging.info("=" * 60)
|
|
@@ -633,10 +661,18 @@ class DatadogAPIPostSearch(BaseDatadogGeneralTool):
|
|
|
633
661
|
params=params,
|
|
634
662
|
)
|
|
635
663
|
|
|
664
|
+
body_query_params = self._body_to_query_params(body)
|
|
665
|
+
web_url = generate_datadog_general_url(
|
|
666
|
+
self.toolset.dd_config,
|
|
667
|
+
endpoint,
|
|
668
|
+
body_query_params,
|
|
669
|
+
)
|
|
670
|
+
|
|
636
671
|
return StructuredToolResult(
|
|
637
672
|
status=StructuredToolResultStatus.SUCCESS,
|
|
638
673
|
data=response_str,
|
|
639
674
|
params=params,
|
|
675
|
+
url=web_url,
|
|
640
676
|
)
|
|
641
677
|
|
|
642
678
|
except DataDogRequestError as e:
|
|
@@ -717,6 +753,7 @@ class ListDatadogAPIResources(BaseDatadogGeneralTool):
|
|
|
717
753
|
status=StructuredToolResultStatus.ERROR,
|
|
718
754
|
error=f"Invalid regex pattern: {e}",
|
|
719
755
|
params=params,
|
|
756
|
+
url="",
|
|
720
757
|
)
|
|
721
758
|
else:
|
|
722
759
|
search_pattern = None
|
|
@@ -847,9 +884,15 @@ class ListDatadogAPIResources(BaseDatadogGeneralTool):
|
|
|
847
884
|
output.append(" • 'logs|metrics' - find logs OR metrics endpoints")
|
|
848
885
|
output.append(" • 'v2.*search$' - find all v2 search endpoints")
|
|
849
886
|
output.append(" • 'security.*signals' - find security signals endpoints")
|
|
887
|
+
doc_url = "https://docs.datadoghq.com/api/latest/"
|
|
888
|
+
if search_regex:
|
|
889
|
+
# URL encode the search parameter - spaces become + in query strings
|
|
890
|
+
search_params = urlencode({"s": search_regex})
|
|
891
|
+
doc_url = f"{doc_url}?{search_params}"
|
|
850
892
|
|
|
851
893
|
return StructuredToolResult(
|
|
852
894
|
status=StructuredToolResultStatus.SUCCESS,
|
|
853
895
|
data="\n".join(output),
|
|
854
896
|
params=params,
|
|
897
|
+
url=doc_url,
|
|
855
898
|
)
|