feat(awooop): expose ai automation work items
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 18s
CD Pipeline / build-and-deploy (push) Successful in 5m18s
CD Pipeline / post-deploy-checks (push) Successful in 1m5s

This commit is contained in:
Your Name
2026-06-29 15:35:47 +08:00
parent 91edba1a27
commit e8228fd2c4
6 changed files with 234 additions and 4 deletions

View File

@@ -596,6 +596,153 @@ def _build_log_integration_taxonomy(
}
def _build_work_item_progress(
*,
trace_ledger: Mapping[str, Any],
log_integration_taxonomy: Mapping[str, Any],
db_read_status: str,
) -> dict[str, Any]:
"""Build ordered work items that the UI and agent can keep advancing."""
taxonomy_rollups = log_integration_taxonomy.get("rollups")
if not isinstance(taxonomy_rollups, Mapping):
taxonomy_rollups = {}
source_families = log_integration_taxonomy.get("source_families")
if not isinstance(source_families, list):
source_families = []
inactive_source_count = _int_value(taxonomy_rollups.get("inactive_source_family_count"))
missing_required = trace_ledger.get("missing_required_stage_ids")
if not isinstance(missing_required, list):
missing_required = []
deployed_readback_complete = (
db_read_status == "ok"
and trace_ledger.get("schema_version") == "ai_agent_autonomous_trace_ledger_v1"
and log_integration_taxonomy.get("schema_version") == "ai_agent_log_integration_taxonomy_v1"
)
ordered_items = [
{
"work_item_id": "P0-A-runtime-truth",
"priority": "P0-A",
"title": "Controlled apply runtime truth readback",
"status": "completed",
"exit_criteria": "production API reports db_read_status=ok and live executor receipts",
},
{
"work_item_id": "P0-B-trace-ledger",
"priority": "P0-B",
"title": "Trace ledger for MCP/log/executor/verifier/KM/PlayBook/Telegram",
"status": "completed" if not missing_required else "in_progress",
"exit_criteria": "trace_ledger exposes required closed-loop stages and missing_required_stage_ids",
},
{
"work_item_id": "P0-C-log-taxonomy",
"priority": "P0-C",
"title": "Project/product/site/service/package/tool log taxonomy",
"status": "completed",
"exit_criteria": "log_integration_taxonomy lists source families, labels, and public-safety policy",
},
{
"work_item_id": "P0-D-ui-visibility",
"priority": "P0-D",
"title": "AwoooP UI shows automation loop and log integration progress",
"status": "completed",
"exit_criteria": "AwoooP, Approvals, Runs, and Work Items show trace/log taxonomy panel",
},
{
"work_item_id": "P0-E-verification-deploy",
"priority": "P0-E",
"title": "Focused verification and production deploy marker readback",
"status": "completed" if deployed_readback_complete else "in_progress",
"exit_criteria": "deploy marker includes this code and production API exposes trace_ledger/log_integration_taxonomy",
"blocker": None if deployed_readback_complete else "waiting_for_successful_gitea_cd_deploy_marker",
},
{
"work_item_id": "P1-A-ingestion-coverage",
"priority": "P1-A",
"title": "Collector and sanitizer coverage for all source families",
"status": "completed" if inactive_source_count == 0 else "in_progress",
"exit_criteria": "all source families have active sanitized classified events",
"remaining_source_family_count": inactive_source_count,
},
{
"work_item_id": "P1-B-agent-decision-wiring",
"priority": "P1-B",
"title": "RAG retrieval to PlayBook select/repair/check-mode/apply/verifier",
"status": "pending",
"exit_criteria": "AI Agent consumes labeled evidence and emits target selector, dry-run, apply, verifier, rollback",
},
{
"work_item_id": "P1-C-learning-loop",
"priority": "P1-C",
"title": "KM / PlayBook trust learning loop",
"status": "pending",
"exit_criteria": "verified execution updates KM entries, trust delta, similar-case clusters, and repair candidates",
},
{
"work_item_id": "P1-D-alert-noise-reduction",
"priority": "P1-D",
"title": "Alert grouping and AI controlled workflow routing",
"status": "pending",
"exit_criteria": "repeated alerts are clustered, deduped, routed to controlled automation, and no longer default to manual handling",
},
{
"work_item_id": "P2-A-ui-ux-productization",
"priority": "P2-A",
"title": "Professional product UI replacing text-heavy surfaces",
"status": "pending",
"exit_criteria": "AI automation status is shown as dense dashboard controls, filters, counters, and action rails",
},
{
"work_item_id": "P2-B-multi-product-expansion",
"priority": "P2-B",
"title": "Reuse taxonomy across AWOOOI products/projects",
"status": "pending",
"exit_criteria": "StockPlatform, VibeWork, MOMO, AwoooGo, and other products report the same log taxonomy contract",
},
]
source_family_items = []
for source in source_families:
if not isinstance(source, Mapping):
continue
total = _int_value(source.get("total"))
source_family_items.append({
"work_item_id": f"P1-A-source-{source.get('source_family_id')}",
"priority": "P1-A",
"source_family_id": source.get("source_family_id"),
"title": f"Ingest and label {source.get('source_family_id')}",
"status": "completed" if total > 0 else "not_started",
"label_dimensions": source.get("label_dimensions") or [],
"next_controlled_action": (
"keep_learning_and_quality_checks"
if total > 0
else source.get("next_action_if_empty")
),
})
all_items = [*ordered_items, *source_family_items]
by_status: dict[str, int] = {}
for item in all_items:
status = str(item.get("status") or "unknown")
by_status[status] = by_status.get(status, 0) + 1
return {
"schema_version": "ai_agent_automation_work_item_progress_v1",
"ordered_items": ordered_items,
"source_family_items": source_family_items,
"rollups": {
"work_item_count": len(all_items),
"ordered_work_item_count": len(ordered_items),
"source_family_work_item_count": len(source_family_items),
"completed_count": by_status.get("completed", 0),
"in_progress_count": by_status.get("in_progress", 0),
"pending_count": by_status.get("pending", 0),
"blocked_count": by_status.get("blocked", 0),
"not_started_count": by_status.get("not_started", 0),
"by_status": by_status,
},
}
def _first_operation(
rows: Iterable[Mapping[str, Any]],
operation_type: str,
@@ -1396,6 +1543,11 @@ def build_runtime_receipt_readback_from_rows(
timeline_summary=timeline_summary,
playbook_trust_summary=playbook_trust_summary,
)
work_item_progress = _build_work_item_progress(
trace_ledger=trace_ledger,
log_integration_taxonomy=log_integration_taxonomy,
db_read_status=db_read_status,
)
apply_summary = operation_summary.get("ansible_apply_executed") or {}
readback = {
"schema_version": _LIVE_READBACK_SCHEMA_VERSION,
@@ -1515,6 +1667,7 @@ def build_runtime_receipt_readback_from_rows(
"autonomous_execution_loop_ledger": loop_ledger,
"trace_ledger": trace_ledger,
"log_integration_taxonomy": log_integration_taxonomy,
"work_item_progress": work_item_progress,
}
if error_type:
readback["error"] = {
@@ -1617,6 +1770,31 @@ def _attach_runtime_receipt_readback(
"recent_classified_event_total"
)
),
"live_work_item_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"work_item_count"
)
),
"live_work_item_completed_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"completed_count"
)
),
"live_work_item_in_progress_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"in_progress_count"
)
),
"live_work_item_pending_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"pending_count"
)
),
"live_work_item_blocked_count": _int_value(
((readback.get("work_item_progress") or {}).get("rollups") or {}).get(
"blocked_count"
)
),
})
return payload

View File

@@ -384,6 +384,28 @@ def test_runtime_receipt_readback_summarizes_live_executor_closure_rows():
assert taxonomy["rollups"]["classified_event_total"] > 0
assert taxonomy["public_safety"]["raw_secret_collection_allowed"] is False
assert taxonomy["public_safety"]["unredacted_payload_storage_allowed"] is False
progress = readback["work_item_progress"]
assert progress["schema_version"] == "ai_agent_automation_work_item_progress_v1"
ordered_ids = [item["work_item_id"] for item in progress["ordered_items"]]
assert ordered_ids == [
"P0-A-runtime-truth",
"P0-B-trace-ledger",
"P0-C-log-taxonomy",
"P0-D-ui-visibility",
"P0-E-verification-deploy",
"P1-A-ingestion-coverage",
"P1-B-agent-decision-wiring",
"P1-C-learning-loop",
"P1-D-alert-noise-reduction",
"P2-A-ui-ux-productization",
"P2-B-multi-product-expansion",
]
assert progress["ordered_items"][4]["status"] == "completed"
assert progress["ordered_items"][5]["status"] == "completed"
assert progress["source_family_items"]
assert {item["status"] for item in progress["source_family_items"]} == {"completed"}
assert progress["rollups"]["source_family_work_item_count"] == 10
assert progress["rollups"]["pending_count"] >= 5
def test_runtime_receipt_readback_classifies_closed_failed_apply_as_ai_repair():

View File

@@ -11355,7 +11355,9 @@
"sources": "Log sources",
"labels": "Label dimensions",
"events": "Classified events",
"learning": "Learning sources"
"learning": "Learning sources",
"workItems": "Work items",
"workItemsDetail": "Active {active} / pending {pending} / blocked {blocked}"
},
"policy": {
"label": "Controlled risk tiers",

View File

@@ -11355,7 +11355,9 @@
"sources": "Log 來源",
"labels": "貼標維度",
"events": "分類事件",
"learning": "學習來源"
"learning": "學習來源",
"workItems": "工作項目",
"workItemsDetail": "進行 {active} / 待辦 {pending} / 阻塞 {blocked}"
},
"policy": {
"label": "受控風險層",

View File

@@ -88,6 +88,15 @@ type RuntimeReceiptReadback = {
learning_source_family_count?: number | null;
} | null;
} | null;
work_item_progress?: {
rollups?: {
work_item_count?: number | null;
completed_count?: number | null;
in_progress_count?: number | null;
pending_count?: number | null;
blocked_count?: number | null;
} | null;
} | null;
latest_flow_closure?: {
apply_op_id?: string | null;
incident_id?: string | null;
@@ -208,6 +217,7 @@ export function AutonomousRuntimeReceiptPanel({
const traceLedger = readback?.trace_ledger;
const logTaxonomy = readback?.log_integration_taxonomy;
const logRollups = logTaxonomy?.rollups ?? {};
const workItemRollups = readback?.work_item_progress?.rollups ?? {};
const latestFlow = readback?.latest_flow_closure;
const rollups = payload?.rollups ?? {};
const closed = ledger?.closed === true || latestFlow?.closed === true;
@@ -400,7 +410,7 @@ export function AutonomousRuntimeReceiptPanel({
})}
</div>
<div className="grid gap-px border-t border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-4">
<div className="grid gap-px border-t border-[#e0ddd4] bg-[#e0ddd4] md:grid-cols-5">
<div className="bg-white px-4 py-3">
<p className="text-xs font-semibold text-[#77736a]">{t("taxonomy.sources")}</p>
<p className="mt-1 text-sm font-semibold text-[#141413]">
@@ -427,6 +437,21 @@ export function AutonomousRuntimeReceiptPanel({
{numberValue(logRollups.learning_source_family_count)}
</p>
</div>
<div className="bg-white px-4 py-3">
<p className="text-xs font-semibold text-[#77736a]">{t("taxonomy.workItems")}</p>
<p className="mt-1 text-sm font-semibold text-[#141413]">
{numberValue(rollups.live_work_item_completed_count ?? workItemRollups.completed_count)}
{" / "}
{numberValue(rollups.live_work_item_count ?? workItemRollups.work_item_count)}
</p>
<p className="mt-1 text-xs leading-5 text-[#5f5b52]">
{t("taxonomy.workItemsDetail", {
active: numberValue(rollups.live_work_item_in_progress_count ?? workItemRollups.in_progress_count),
pending: numberValue(rollups.live_work_item_pending_count ?? workItemRollups.pending_count),
blocked: numberValue(rollups.live_work_item_blocked_count ?? workItemRollups.blocked_count),
})}
</p>
</div>
</div>
{mode === "full" ? (

View File

@@ -3,7 +3,8 @@
**完成內容**
- `agent-autonomous-runtime-control` readback 新增 `trace_ledger`,把 MCP、service/package log evidence、executor log projection、candidate、check-mode、controlled apply、auto-repair receipt、post-apply verifier、KM/RAG、PlayBook trust、timeline projection、Telegram receipt 收斂為 12 個 public-safe 節點。
- 新增 `log_integration_taxonomy`,把專案 / 產品 / 網站 / 服務 / 套件 / 工具 / incident / operation / playbook 等 label dimensions 與 10 類 source families 明確列入 API供 AI Agent 分類、分群、RAG retrieve、PlayBook 選擇與學習回寫。
- AwoooP 主頁、Approvals、Runs、Work Items 新增 `AutonomousRuntimeReceiptPanel`,顯示 Loop / Trace / MCP / Logs / Apply / Verifier / KM-RAG / PlayBook / Telegram 與 Log 來源、貼標維度、分類事件、學習來源
- 新增 `work_item_progress`,把 P0-A 到 P2-B 的 ordered work items 與每個 source family 接入狀態列成可計數 readbackcompleted / in_progress / pending / blocked / not_started
- AwoooP 主頁、Approvals、Runs、Work Items 新增 `AutonomousRuntimeReceiptPanel`,顯示 Loop / Trace / MCP / Logs / Apply / Verifier / KM-RAG / PlayBook / Telegram 與 Log 來源、貼標維度、分類事件、學習來源、工作項目完成度。
- 補 `sidebar.iwooos` / `sidebar.iwooosSecurityCompliance` i18n避免 IwoooS 導航入口在 runtime console 出現 missing message。
**驗證結果**