@misterhuydo/sentinel 1.5.43 → 1.5.44

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@misterhuydo/sentinel",
3
- "version": "1.5.43",
3
+ "version": "1.5.44",
4
4
  "description": "Sentinel — Autonomous DevOps Agent installer and manager",
5
5
  "bin": {
6
6
  "sentinel": "./bin/sentinel.js"
@@ -1 +1 @@
1
- __version__ = "1.5.43"
1
+ __version__ = "1.5.44"
@@ -2069,6 +2069,36 @@ def _filter_log_sources(props_files: list, source_hint: str) -> list:
2069
2069
  return matched
2070
2070
 
2071
2071
 
2072
+ def _auto_health_check(source_hint: str, cfg_loader) -> dict | None:
2073
+ """
2074
+ If any log source or repo matching source_hint has a HEALTH_URL, call it and return
2075
+ the result so it can be injected into fetch/filter responses automatically.
2076
+ Returns None if no health URL is configured or the call fails silently.
2077
+ """
2078
+ try:
2079
+ import requests as _req
2080
+ url = ""
2081
+ for src_name, src in cfg_loader.log_sources.items():
2082
+ if source_hint.lower() in src_name.lower() and getattr(src, "health_url", ""):
2083
+ url = src.health_url
2084
+ break
2085
+ if not url:
2086
+ for repo_name, repo in cfg_loader.repos.items():
2087
+ if source_hint.lower() in repo_name.lower() and repo.health_url:
2088
+ url = repo.health_url
2089
+ break
2090
+ if not url:
2091
+ return None
2092
+ resp = _req.get(url, timeout=8)
2093
+ try:
2094
+ data = resp.json()
2095
+ except Exception:
2096
+ data = resp.text[:500]
2097
+ return {"health_url": url, "status_code": resp.status_code, "health": data}
2098
+ except Exception:
2099
+ return None
2100
+
2101
+
2072
2102
  # ── Tool execution ────────────────────────────────────────────────────────────
2073
2103
 
2074
2104
  async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=None, user_id: str = "", channel: str = "", is_admin: bool = False) -> str:
@@ -2929,6 +2959,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2929
2959
  sources_searched = [d.name + (" [temp]" if is_temp else "") for d, is_temp in search_pairs]
2930
2960
  if total == 0:
2931
2961
  has_temp = bool(temp_dirs)
2962
+ health = _auto_health_check(source_f, cfg_loader) if source_f else None
2932
2963
  return json.dumps({
2933
2964
  "query": query_f,
2934
2965
  "total_matches": 0,
@@ -2939,6 +2970,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2939
2970
  + "If searching for a specific log line from a new feature, use fetch_logs "
2940
2971
  "with a matching grep_filter first — the default filter only captures WARN/ERROR."
2941
2972
  ),
2973
+ **({"service_health": health} if health else {}),
2942
2974
  })
2943
2975
 
2944
2976
  # Pattern grouping: count occurrences of each error signature
@@ -2980,6 +3012,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2980
3012
  except Exception:
2981
3013
  pass
2982
3014
 
3015
+ health = _auto_health_check(source_f, cfg_loader) if source_f else None
2983
3016
  return json.dumps({
2984
3017
  "query": query_f,
2985
3018
  "total_matches": total,
@@ -2989,6 +3022,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
2989
3022
  "sample_lines": sample_lines,
2990
3023
  "time_span": time_span,
2991
3024
  "capped": total >= max_matches,
3025
+ **({"service_health": health} if health else {}),
2992
3026
  })
2993
3027
 
2994
3028
  if name == "trigger_poll":
@@ -3141,7 +3175,12 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
3141
3175
  except Exception as e:
3142
3176
  results.append({"source": props.stem, "error": str(e)})
3143
3177
 
3144
- return json.dumps({"fetched": len(results), "results": results})
3178
+ health = _auto_health_check(source_filter, cfg_loader) if source_filter else None
3179
+ return json.dumps({
3180
+ "fetched": len(results),
3181
+ "results": results,
3182
+ **({"service_health": health} if health else {}),
3183
+ })
3145
3184
 
3146
3185
  if name == "watch_bot":
3147
3186
  if not is_admin: