atlasbot: improve runbook and hardware snapshot
This commit is contained in:
parent
2386d5c832
commit
90688c244d
@ -297,6 +297,18 @@ class AnswerEngine:
|
||||
runbook_fix = _needs_runbook_fix(reply, runbook_paths)
|
||||
runbook_needed = _needs_runbook_reference(normalized, runbook_paths, reply)
|
||||
needs_evidence = _needs_evidence_fix(reply, classify)
|
||||
resolved_runbook = None
|
||||
if runbook_paths and (runbook_fix or runbook_needed):
|
||||
resolver_prompt = prompts.RUNBOOK_SELECT_PROMPT + "\nQuestion: " + normalized
|
||||
resolver_raw = await call_llm(
|
||||
prompts.RUNBOOK_SELECT_SYSTEM,
|
||||
resolver_prompt,
|
||||
context="AllowedRunbooks:\n" + "\n".join(runbook_paths),
|
||||
model=plan.fast_model,
|
||||
tag="runbook_select",
|
||||
)
|
||||
resolver = _parse_json_block(resolver_raw, fallback={})
|
||||
resolved_runbook = resolver.get("path") if isinstance(resolver.get("path"), str) else None
|
||||
if (snapshot_context and needs_evidence) or unknown_nodes or unknown_namespaces or runbook_fix or runbook_needed:
|
||||
if observer:
|
||||
observer("evidence_fix", "repairing missing evidence")
|
||||
@ -307,6 +319,8 @@ class AnswerEngine:
|
||||
extra_bits.append("UnknownNamespaces: " + ", ".join(sorted(unknown_namespaces)))
|
||||
if runbook_paths:
|
||||
extra_bits.append("AllowedRunbooks: " + ", ".join(runbook_paths))
|
||||
if resolved_runbook:
|
||||
extra_bits.append("ResolvedRunbook: " + resolved_runbook)
|
||||
if allowed_nodes:
|
||||
extra_bits.append("AllowedNodes: " + ", ".join(allowed_nodes))
|
||||
if allowed_namespaces:
|
||||
@ -847,11 +861,14 @@ def _needs_evidence_fix(reply: str, classify: dict[str, Any]) -> bool:
|
||||
"need to",
|
||||
"would need",
|
||||
"does not provide",
|
||||
"does not mention",
|
||||
"not mention",
|
||||
"not provided",
|
||||
"not in context",
|
||||
"not referenced",
|
||||
"missing",
|
||||
"no specific",
|
||||
"no information",
|
||||
)
|
||||
if classify.get("needs_snapshot") and any(marker in lowered for marker in missing_markers):
|
||||
return True
|
||||
|
||||
@ -104,6 +104,17 @@ EVIDENCE_FIX_PROMPT = (
|
||||
"documentation or checklist questions and do not invent new paths."
|
||||
)
|
||||
|
||||
RUNBOOK_SELECT_SYSTEM = (
|
||||
CLUSTER_SYSTEM
|
||||
+ " Select the single best runbook path from the allowed list. "
|
||||
+ "Return JSON only."
|
||||
)
|
||||
|
||||
RUNBOOK_SELECT_PROMPT = (
|
||||
"Pick the best runbook path for the question from the AllowedRunbooks list. "
|
||||
"Return JSON with field: path. If none apply, return {\"path\": \"\"}."
|
||||
)
|
||||
|
||||
DRAFT_SELECT_PROMPT = (
|
||||
"Pick the best draft for accuracy, clarity, and helpfulness. "
|
||||
"Return JSON with field: best (1-based index)."
|
||||
|
||||
@ -625,6 +625,21 @@ def _append_hardware(lines: list[str], summary: dict[str, Any]) -> None:
|
||||
lines.append("hardware: " + "; ".join(sorted(parts)))
|
||||
|
||||
|
||||
def _append_hardware_groups(lines: list[str], summary: dict[str, Any]) -> None:
|
||||
hardware = summary.get("hardware") if isinstance(summary.get("hardware"), dict) else {}
|
||||
if not hardware:
|
||||
return
|
||||
parts = []
|
||||
for key, names in hardware.items():
|
||||
if not isinstance(names, list):
|
||||
continue
|
||||
name_list = _format_names([str(name) for name in names if name])
|
||||
if name_list:
|
||||
parts.append(f"{key}={name_list}")
|
||||
if parts:
|
||||
lines.append("hardware_nodes: " + "; ".join(sorted(parts)))
|
||||
|
||||
|
||||
def _append_node_ages(lines: list[str], summary: dict[str, Any]) -> None:
|
||||
ages = summary.get("node_ages") if isinstance(summary.get("node_ages"), list) else []
|
||||
if not ages:
|
||||
@ -1308,6 +1323,15 @@ def _append_postgres(lines: list[str], summary: dict[str, Any]) -> None:
|
||||
hottest=hottest,
|
||||
)
|
||||
)
|
||||
used = postgres.get("used")
|
||||
max_conn = postgres.get("max")
|
||||
if used is not None or max_conn is not None:
|
||||
lines.append(
|
||||
"postgres_connections_total: used={used}, max={max}".format(
|
||||
used=_format_float(used),
|
||||
max=_format_float(max_conn),
|
||||
)
|
||||
)
|
||||
by_db = postgres.get("by_db")
|
||||
if isinstance(by_db, list) and by_db:
|
||||
parts = []
|
||||
@ -1805,6 +1829,7 @@ def summary_text(snapshot: dict[str, Any] | None) -> str:
|
||||
lines.append("snapshot: " + ", ".join(bits))
|
||||
_append_nodes(lines, summary)
|
||||
_append_hardware(lines, summary)
|
||||
_append_hardware_groups(lines, summary)
|
||||
_append_lexicon(lines, summary)
|
||||
_append_pressure(lines, summary)
|
||||
_append_node_facts(lines, summary)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user