Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

91 lines
3.3 KiB
Python

"""Publish-findings node — entry points for the investigation pipeline.
Node contract:
Entrypoint : deliver(state: InvestigationState) -> dict[str, Any]
Reads : root_cause, validated_claims, non_validated_claims,
remediation_steps, correlation, evidence, resolved_integrations,
slack_context, telegram_context, whatsapp_context,
discord_context, problem_md, masking_context, opensre_evaluate
Writes : slack_message, report, opensre_llm_eval (optional)
"""
from __future__ import annotations
from typing import Any, cast
from core.state import InvestigationState
from platform.masking import MaskingContext
from platform.notifications.ingest_delivery import create_investigation_and_attach_url
from tools.investigation.reporting.context import build_report_context
from tools.investigation.reporting.delivery import dispatch_report
from tools.investigation.reporting.evaluation import run_optional_opensre_evaluation
from tools.investigation.reporting.formatters.messages import (
ReportMessages,
build_report_messages,
)
from tools.investigation.reporting.renderers.editor import open_in_editor
from tools.investigation.reporting.renderers.terminal import render_report
from tools.investigation.reporting.upstream_correlation import (
enrich_upstream_correlation,
)
def deliver(state: InvestigationState) -> dict[str, Any]:
"""Format and deliver the investigation report to all configured channels.
Returns state updates with slack_message and report fields.
"""
state_dict = dict(state)
extra_updates = run_optional_opensre_evaluation(state_dict)
return {**generate_report(state), **extra_updates}
def generate_report(
state: InvestigationState,
*,
render_terminal: bool = True,
open_editor: bool = True,
) -> dict[str, Any]:
"""Generate and publish the final RCA report."""
correlation_updates = enrich_upstream_correlation(state)
enriched_state = cast(InvestigationState, {**dict(state), **correlation_updates})
ctx = build_report_context(enriched_state)
short_summary = enriched_state.get("problem_md")
messages = build_report_messages(ctx)
# Restore any masked infrastructure identifiers in user-facing output.
# No-op when masking is disabled or the state has no placeholders.
masking_ctx = MaskingContext.from_state(dict(enriched_state))
messages = ReportMessages(
slack_text=masking_ctx.unmask(messages.slack_text),
telegram_html=masking_ctx.unmask(messages.telegram_html),
whatsapp_text=masking_ctx.unmask(messages.whatsapp_text),
slack_blocks=masking_ctx.unmask_value(messages.slack_blocks),
)
if isinstance(short_summary, str):
short_summary = masking_ctx.unmask(short_summary)
investigation_id, investigation_url = create_investigation_and_attach_url(
enriched_state,
messages.slack_text,
short_summary,
)
if render_terminal:
render_report(messages.slack_text)
if open_editor:
open_in_editor(messages.slack_text)
dispatch_report(
enriched_state,
messages,
investigation_id=investigation_id,
investigation_url=investigation_url,
)
return {
**correlation_updates,
"slack_message": messages.slack_text,
"report": messages.slack_text,
}