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_fix = _needs_runbook_fix(reply, runbook_paths)
|
||||||
runbook_needed = _needs_runbook_reference(normalized, runbook_paths, reply)
|
runbook_needed = _needs_runbook_reference(normalized, runbook_paths, reply)
|
||||||
needs_evidence = _needs_evidence_fix(reply, classify)
|
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 (snapshot_context and needs_evidence) or unknown_nodes or unknown_namespaces or runbook_fix or runbook_needed:
|
||||||
if observer:
|
if observer:
|
||||||
observer("evidence_fix", "repairing missing evidence")
|
observer("evidence_fix", "repairing missing evidence")
|
||||||
@ -307,6 +319,8 @@ class AnswerEngine:
|
|||||||
extra_bits.append("UnknownNamespaces: " + ", ".join(sorted(unknown_namespaces)))
|
extra_bits.append("UnknownNamespaces: " + ", ".join(sorted(unknown_namespaces)))
|
||||||
if runbook_paths:
|
if runbook_paths:
|
||||||
extra_bits.append("AllowedRunbooks: " + ", ".join(runbook_paths))
|
extra_bits.append("AllowedRunbooks: " + ", ".join(runbook_paths))
|
||||||
|
if resolved_runbook:
|
||||||
|
extra_bits.append("ResolvedRunbook: " + resolved_runbook)
|
||||||
if allowed_nodes:
|
if allowed_nodes:
|
||||||
extra_bits.append("AllowedNodes: " + ", ".join(allowed_nodes))
|
extra_bits.append("AllowedNodes: " + ", ".join(allowed_nodes))
|
||||||
if allowed_namespaces:
|
if allowed_namespaces:
|
||||||
@ -847,11 +861,14 @@ def _needs_evidence_fix(reply: str, classify: dict[str, Any]) -> bool:
|
|||||||
"need to",
|
"need to",
|
||||||
"would need",
|
"would need",
|
||||||
"does not provide",
|
"does not provide",
|
||||||
|
"does not mention",
|
||||||
|
"not mention",
|
||||||
"not provided",
|
"not provided",
|
||||||
"not in context",
|
"not in context",
|
||||||
"not referenced",
|
"not referenced",
|
||||||
"missing",
|
"missing",
|
||||||
"no specific",
|
"no specific",
|
||||||
|
"no information",
|
||||||
)
|
)
|
||||||
if classify.get("needs_snapshot") and any(marker in lowered for marker in missing_markers):
|
if classify.get("needs_snapshot") and any(marker in lowered for marker in missing_markers):
|
||||||
return True
|
return True
|
||||||
|
|||||||
@ -104,6 +104,17 @@ EVIDENCE_FIX_PROMPT = (
|
|||||||
"documentation or checklist questions and do not invent new paths."
|
"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 = (
|
DRAFT_SELECT_PROMPT = (
|
||||||
"Pick the best draft for accuracy, clarity, and helpfulness. "
|
"Pick the best draft for accuracy, clarity, and helpfulness. "
|
||||||
"Return JSON with field: best (1-based index)."
|
"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)))
|
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:
|
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 []
|
ages = summary.get("node_ages") if isinstance(summary.get("node_ages"), list) else []
|
||||||
if not ages:
|
if not ages:
|
||||||
@ -1308,6 +1323,15 @@ def _append_postgres(lines: list[str], summary: dict[str, Any]) -> None:
|
|||||||
hottest=hottest,
|
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")
|
by_db = postgres.get("by_db")
|
||||||
if isinstance(by_db, list) and by_db:
|
if isinstance(by_db, list) and by_db:
|
||||||
parts = []
|
parts = []
|
||||||
@ -1805,6 +1829,7 @@ def summary_text(snapshot: dict[str, Any] | None) -> str:
|
|||||||
lines.append("snapshot: " + ", ".join(bits))
|
lines.append("snapshot: " + ", ".join(bits))
|
||||||
_append_nodes(lines, summary)
|
_append_nodes(lines, summary)
|
||||||
_append_hardware(lines, summary)
|
_append_hardware(lines, summary)
|
||||||
|
_append_hardware_groups(lines, summary)
|
||||||
_append_lexicon(lines, summary)
|
_append_lexicon(lines, summary)
|
||||||
_append_pressure(lines, summary)
|
_append_pressure(lines, summary)
|
||||||
_append_node_facts(lines, summary)
|
_append_node_facts(lines, summary)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user