@misterhuydo/sentinel 1.5.43 → 1.5.45
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 +1 @@
|
|
|
1
|
-
__version__ = "1.5.
|
|
1
|
+
__version__ = "1.5.45"
|
|
@@ -563,27 +563,23 @@ When to act vs. when to ask:
|
|
|
563
563
|
When filter_logs returns no hits after a recent release, always retry with search_logs before
|
|
564
564
|
telling the user the log line isn't there.
|
|
565
565
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
566
|
-
LOG RESULTS
|
|
566
|
+
LOG SEARCH RESULTS — REPORT ONLY WHAT WAS FOUND
|
|
567
567
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
568
|
-
|
|
569
|
-
|
|
568
|
+
When the user asks to filter, search, or fetch logs: report exactly what the tool returned.
|
|
569
|
+
Do NOT add deployment status, release status, version conclusions, or "next steps" about Jenkins.
|
|
570
|
+
The user asked for log lines — give them the log lines (or "no matches found"), nothing more.
|
|
570
571
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
"Zero hits for '<feature log pattern>'. Release X.Y.Z has not deployed."
|
|
576
|
-
"Found old log entries but no new ones — servers are still on the previous version."
|
|
577
|
-
"The new code from release X.Y.Z is still not deployed."
|
|
572
|
+
WRONG (user asked for log results, not deployment analysis):
|
|
573
|
+
"Found 3 matches. The new code from release X.Y.Z is still not deployed."
|
|
574
|
+
"No matches — the servers haven't picked up the new release yet."
|
|
575
|
+
"Zero hits. Check Jenkins to confirm the build status."
|
|
578
576
|
|
|
579
577
|
CORRECT:
|
|
580
|
-
"
|
|
581
|
-
|
|
578
|
+
"3 matches found: [table of results]"
|
|
579
|
+
"No matches for '<pattern>' in <source>."
|
|
582
580
|
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
2. If no HEALTH_URL is configured: search_logs with query "Starting|started in|version|initialized".
|
|
586
|
-
NEVER state deployment status without calling check_health first.
|
|
581
|
+
Deployment/version questions are separate. If the user asks "is version X deployed?", THEN
|
|
582
|
+
call check_health (returns live version from HEALTH_URL) or search_logs for startup lines.
|
|
587
583
|
- If a tool call will take a moment (search, fetch, pull), prefix your reply with a brief "working" line ending in "..." before the results, e.g. "Searching SSOLWA for TryDig activity..." then the actual output.
|
|
588
584
|
Never just say a working line and stop — always follow it with the results in the same message.
|
|
589
585
|
|
|
@@ -2069,6 +2065,36 @@ def _filter_log_sources(props_files: list, source_hint: str) -> list:
|
|
|
2069
2065
|
return matched
|
|
2070
2066
|
|
|
2071
2067
|
|
|
2068
|
+
def _auto_health_check(source_hint: str, cfg_loader) -> dict | None:
|
|
2069
|
+
"""
|
|
2070
|
+
If any log source or repo matching source_hint has a HEALTH_URL, call it and return
|
|
2071
|
+
the result so it can be injected into fetch/filter responses automatically.
|
|
2072
|
+
Returns None if no health URL is configured or the call fails silently.
|
|
2073
|
+
"""
|
|
2074
|
+
try:
|
|
2075
|
+
import requests as _req
|
|
2076
|
+
url = ""
|
|
2077
|
+
for src_name, src in cfg_loader.log_sources.items():
|
|
2078
|
+
if source_hint.lower() in src_name.lower() and getattr(src, "health_url", ""):
|
|
2079
|
+
url = src.health_url
|
|
2080
|
+
break
|
|
2081
|
+
if not url:
|
|
2082
|
+
for repo_name, repo in cfg_loader.repos.items():
|
|
2083
|
+
if source_hint.lower() in repo_name.lower() and repo.health_url:
|
|
2084
|
+
url = repo.health_url
|
|
2085
|
+
break
|
|
2086
|
+
if not url:
|
|
2087
|
+
return None
|
|
2088
|
+
resp = _req.get(url, timeout=8)
|
|
2089
|
+
try:
|
|
2090
|
+
data = resp.json()
|
|
2091
|
+
except Exception:
|
|
2092
|
+
data = resp.text[:500]
|
|
2093
|
+
return {"health_url": url, "status_code": resp.status_code, "health": data}
|
|
2094
|
+
except Exception:
|
|
2095
|
+
return None
|
|
2096
|
+
|
|
2097
|
+
|
|
2072
2098
|
# ── Tool execution ────────────────────────────────────────────────────────────
|
|
2073
2099
|
|
|
2074
2100
|
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 +2955,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2929
2955
|
sources_searched = [d.name + (" [temp]" if is_temp else "") for d, is_temp in search_pairs]
|
|
2930
2956
|
if total == 0:
|
|
2931
2957
|
has_temp = bool(temp_dirs)
|
|
2958
|
+
health = _auto_health_check(source_f, cfg_loader) if source_f else None
|
|
2932
2959
|
return json.dumps({
|
|
2933
2960
|
"query": query_f,
|
|
2934
2961
|
"total_matches": 0,
|
|
@@ -2939,6 +2966,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2939
2966
|
+ "If searching for a specific log line from a new feature, use fetch_logs "
|
|
2940
2967
|
"with a matching grep_filter first — the default filter only captures WARN/ERROR."
|
|
2941
2968
|
),
|
|
2969
|
+
**({"service_health": health} if health else {}),
|
|
2942
2970
|
})
|
|
2943
2971
|
|
|
2944
2972
|
# Pattern grouping: count occurrences of each error signature
|
|
@@ -2980,6 +3008,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2980
3008
|
except Exception:
|
|
2981
3009
|
pass
|
|
2982
3010
|
|
|
3011
|
+
health = _auto_health_check(source_f, cfg_loader) if source_f else None
|
|
2983
3012
|
return json.dumps({
|
|
2984
3013
|
"query": query_f,
|
|
2985
3014
|
"total_matches": total,
|
|
@@ -2989,6 +3018,7 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
2989
3018
|
"sample_lines": sample_lines,
|
|
2990
3019
|
"time_span": time_span,
|
|
2991
3020
|
"capped": total >= max_matches,
|
|
3021
|
+
**({"service_health": health} if health else {}),
|
|
2992
3022
|
})
|
|
2993
3023
|
|
|
2994
3024
|
if name == "trigger_poll":
|
|
@@ -3141,7 +3171,12 @@ async def _run_tool(name: str, inputs: dict, cfg_loader, store, slack_client=Non
|
|
|
3141
3171
|
except Exception as e:
|
|
3142
3172
|
results.append({"source": props.stem, "error": str(e)})
|
|
3143
3173
|
|
|
3144
|
-
|
|
3174
|
+
health = _auto_health_check(source_filter, cfg_loader) if source_filter else None
|
|
3175
|
+
return json.dumps({
|
|
3176
|
+
"fetched": len(results),
|
|
3177
|
+
"results": results,
|
|
3178
|
+
**({"service_health": health} if health else {}),
|
|
3179
|
+
})
|
|
3145
3180
|
|
|
3146
3181
|
if name == "watch_bot":
|
|
3147
3182
|
if not is_admin:
|