diff --git a/apps/web/messages/en.json b/apps/web/messages/en.json index 3bbb27a7..3b70cddd 100644 --- a/apps/web/messages/en.json +++ b/apps/web/messages/en.json @@ -9047,7 +9047,10 @@ "blocker": "Current blocker", "diagnosis": "SSH diagnosis", "receipt": "Receipt contract", - "receiptValue": "{inputs} inputs / {outputs} outputs" + "receiptValue": "{inputs} inputs / {outputs} outputs", + "currentCd": "Latest CD run", + "currentCdValue": "#{run} · {status}", + "currentCdDetail": "closure: {state}" }, "rootCause": { "sessionTimeout": "Key accepted, session timeout", diff --git a/apps/web/messages/zh-TW.json b/apps/web/messages/zh-TW.json index 77c3baac..2de74a28 100644 --- a/apps/web/messages/zh-TW.json +++ b/apps/web/messages/zh-TW.json @@ -9047,7 +9047,10 @@ "blocker": "目前卡點", "diagnosis": "SSH 診斷", "receipt": "收件契約", - "receiptValue": "{inputs} inputs / {outputs} outputs" + "receiptValue": "{inputs} inputs / {outputs} outputs", + "currentCd": "最新 CD run", + "currentCdValue": "#{run} · {status}", + "currentCdDetail": "closure:{state}" }, "rootCause": { "sessionTimeout": "Key accepted,session timeout", diff --git a/apps/web/src/app/[locale]/awooop/work-items/page.tsx b/apps/web/src/app/[locale]/awooop/work-items/page.tsx index 4fb68980..2e7b59b9 100644 --- a/apps/web/src/app/[locale]/awooop/work-items/page.tsx +++ b/apps/web/src/app/[locale]/awooop/work-items/page.tsx @@ -1037,6 +1037,9 @@ type PriorityWorkOrderResponse = { ai_loop_current_blocker_harbor_recovery_receipt_output_ids?: string[] | null; ai_loop_current_blocker_queue_readback_normalizer_contract_count?: number | null; ai_loop_current_blocker_queue_readback_normalizer_field_ids?: string[] | null; + ai_loop_current_blocker_current_cd_run_id?: string | null; + ai_loop_current_blocker_current_cd_run_status?: string | null; + ai_loop_current_blocker_deployment_closure_state?: string | null; ai_loop_current_blocker_safe_next_action_id?: string | null; ai_loop_current_blocker_safe_next_action_stage?: string | null; ai_loop_current_blocker_safe_next_action_requires_local_console?: boolean | null; @@ -1051,6 +1054,9 @@ type PriorityWorkOrderResponse = { ai_loop_current_blocker_harbor_recovery_receipt_input_ids?: string[] | null; ai_loop_current_blocker_harbor_recovery_receipt_output_ids?: string[] | null; ai_loop_current_blocker_queue_readback_normalizer_field_ids?: string[] | null; + ai_loop_current_blocker_current_cd_run_id?: string | null; + ai_loop_current_blocker_current_cd_run_status?: string | null; + ai_loop_current_blocker_deployment_closure_state?: string | null; ai_loop_current_blocker_safe_next_action_id?: string | null; ai_loop_current_blocker_safe_next_action_stage?: string | null; ai_loop_current_blocker_safe_next_action?: string | null; @@ -7828,6 +7834,18 @@ function AiLoopLogSourceTagsPanel({ summary?.ai_loop_current_blocker_safe_next_action_requires_local_console ?? evidence?.ai_loop_current_blocker_safe_next_action_requires_local_console ?? false; + const currentCdRunId = + summary?.ai_loop_current_blocker_current_cd_run_id ?? + evidence?.ai_loop_current_blocker_current_cd_run_id ?? + ""; + const currentCdRunStatus = + summary?.ai_loop_current_blocker_current_cd_run_status ?? + evidence?.ai_loop_current_blocker_current_cd_run_status ?? + ""; + const deploymentClosureState = + summary?.ai_loop_current_blocker_deployment_closure_state ?? + evidence?.ai_loop_current_blocker_deployment_closure_state ?? + ""; const labelMap: Record = { project_id: t("tagLabels.projectId"), product: t("tagLabels.product"), @@ -7922,6 +7940,24 @@ function AiLoopLogSourceTagsPanel({ }), tone: "border-[#cbd7bf] bg-[#f4faef] text-[#3d6b24]", }, + { + key: "current-cd", + icon: GitBranch, + label: t("visual.currentCd"), + value: currentCdRunId + ? t("visual.currentCdValue", { + run: currentCdRunId, + status: currentCdRunStatus || "--", + }) + : currentCdRunStatus || "--", + detail: deploymentClosureState + ? t("visual.currentCdDetail", { state: deploymentClosureState }) + : undefined, + tone: + currentCdRunStatus === "Failure" + ? "border-[#f0c6a8] bg-[#fff8f1] text-[#9a4d16]" + : "border-[#c9d8ea] bg-[#eef5ff] text-[#1f5b9b]", + }, { key: "safe-next-action", icon: ArrowRight, diff --git a/ops/runner/test_cd_controlled_runtime_profile.py b/ops/runner/test_cd_controlled_runtime_profile.py index 735d141d..065c3ada 100644 --- a/ops/runner/test_cd_controlled_runtime_profile.py +++ b/ops/runner/test_cd_controlled_runtime_profile.py @@ -546,9 +546,13 @@ def test_ai_log_controlled_writeback_consumer_stays_on_controlled_runtime_profil text = _workflow_text() expected_sources = [ "apps/api/src/services/ai_agent_log_controlled_writeback_consumer_readback.py)", + "apps/api/src/services/ai_agent_log_controlled_writeback_consumer_apply.py)", "apps/api/tests/test_ai_agent_log_controlled_writeback_consumer_readback_api.py)", + "apps/api/tests/test_ai_agent_log_controlled_writeback_consumer_apply_api.py)", "src/services/ai_agent_log_controlled_writeback_consumer_readback.py", + "src/services/ai_agent_log_controlled_writeback_consumer_apply.py", "tests/test_ai_agent_log_controlled_writeback_consumer_readback_api.py", + "tests/test_ai_agent_log_controlled_writeback_consumer_apply_api.py", ] for source in expected_sources: assert source in text