From 8a1f25c64072fe8cc96284950291f2ef73797324 Mon Sep 17 00:00:00 2001 From: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> Date: Mon, 2 Nov 2026 08:26:12 +0530 Subject: [PATCH] fix(steward): keep periodic report state readable after executor changes Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> --- apps/presentation/dashboard/src/data/chat.ts | 4 +- .../private-conversation-panel.tsx | 2 +- .../steward-managed-mode.tsx | 20 +++--- .../personal-workspace/steward-report.tsx | 10 +-- .../retained-executor-before.png | Bin 0 -> 113721 bytes .../retained-executor-desktop.png | Bin 0 -> 102249 bytes .../retained-executor-narrow.png | Bin 0 -> 59076 bytes docs/product/periodic-reports.md | 23 +++++++ .../steward_report_fixture.py | 28 +++++++++ .../lark/private_conversation_api.py | 7 ++- tests/test_native_steward_managed_mode.py | 59 +++++++++++++++++- 11 files changed, 136 insertions(+), 17 deletions(-) create mode 100644 docs/assets/personal-workspace/steward-reports/retained-executor-before.png create mode 100644 docs/assets/personal-workspace/steward-reports/retained-executor-desktop.png create mode 100644 docs/assets/personal-workspace/steward-reports/retained-executor-narrow.png diff --git a/apps/presentation/dashboard/src/data/chat.ts b/apps/presentation/dashboard/src/data/chat.ts index a176506cb6..5b46e1cc0a 100644 --- a/apps/presentation/dashboard/src/data/chat.ts +++ b/apps/presentation/dashboard/src/data/chat.ts @@ -2772,6 +2772,7 @@ const privateConversationSchema = z.object({ ]).optional(), managed_steward: z.discriminatedUnion("available", [ z.object({available: z.literal(true), prepared: z.boolean(), scheduling_enabled: z.boolean(), + execution_available: z.boolean().optional(), execution_error_code: z.string().optional(), goal_active: z.boolean().optional(), monitor: z.object({todo_id: z.string(), status: z.string(), cadence_minutes: z.number().int().nullable(), next_due_at: z.string().nullable(), last_checked_at: z.string().nullable()}).nullable().optional(), @@ -2784,7 +2785,8 @@ const privateConversationSchema = z.object({ z.object({available: z.literal(false), error_code: z.string()}), ]).optional(), goal_id: z.string().optional(), agent_id: z.string().optional(), session_id: z.string().optional()}), - z.object({available: z.literal(false), error_code: z.string()}), + z.object({available: z.literal(false), error_code: z.string(), + execution_available: z.boolean().optional(), execution_error_code: z.string().optional()}), ]).optional(), agent_candidates: z.array(privateAgentSessionSchema).default([]), agent_targets: z.array(privateAgentTargetSchema).default([]), }); diff --git a/apps/presentation/dashboard/src/features/personal-workspace/private-conversation-panel.tsx b/apps/presentation/dashboard/src/features/personal-workspace/private-conversation-panel.tsx index 539dd3e51d..94bbc9314c 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/private-conversation-panel.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/private-conversation-panel.tsx @@ -193,7 +193,7 @@ export function PrivateConversationPanel({apps, onOpenOriginal}: {apps: LarkApp[ {row.recovery_count > 0 ?
{zh ? "存在尚未确认的发送回执。服务会读取原回执恢复;不要重新发送同一任务。检查 App 登录、权限和原会话后刷新状态。" : "A send receipt is unconfirmed. The service reads the original receipt to recover; avoid resending the same task. Check this App login, permissions and original Session, then refresh status."}
: null} {!row.context_available ?{zh ? "工作区授权已失效;请恢复原工作区或重新选择。旧会话不会移到其它工作区。" : "The workspace grant is unavailable. Restore the original workspace or select a new one; the old Session will not move."}
: null} {row.context_kind === "project" && row.audience !== "group" ?{zh + ? "当前执行器不支持此原生周期任务;原计划、窗口和回执均保留,执行与修改暂不可用。" + : "The current executor does not support this native scheduled work. Original schedules, windows and receipts are retained; execution and changes are unavailable."}
: null} {!state.available ?{zh ? "管家工作身份暂不可用;请检查原会话和连接后重试。" : "The steward identity is unavailable. Check the original conversation and connection, then retry."}
: state.prepared ? <> -{state.scheduling_enabled +
{!executionAvailable ? (zh ? "原监控配置已保留。" : "Original monitoring configuration retained.") : state.scheduling_enabled ? (zh ? "授权 Goal 状态监控已启用。" : "Authorized Goal monitoring is enabled.") : state.monitor ? (zh ? "状态监控已暂停。" : "Goal monitoring is paused.") : (zh ? "管家身份已准备,状态监控尚未启用。" : "The steward identity is prepared; monitoring is not enabled.")}
{zh ? "状态检查复用原生监控,不调用模型。" : "State checks use the native monitor without model calls."}
{zh ? "管家的工作 Goal 已停止;恢复原 Goal 后才能继续监控。" : "The steward Goal is stopped. Resume that original Goal before monitoring."}
: null} - {state.monitor ?{state.scheduling_enabled ? (zh ? "下次检查:" : "Next check: ") : (zh ? "保留的到期时间:" : "Retained deadline: ")}{state.monitor.next_due_at ? new Date(state.monitor.next_due_at).toLocaleString(zh ? "zh-CN" : "en-US") : (zh ? "未排期" : "Unscheduled")} + {state.monitor ?
{executionAvailable && state.scheduling_enabled ? (zh ? "下次检查:" : "Next check: ") : (zh ? "保留的到期时间:" : "Retained deadline: ")}{state.monitor.next_due_at ? new Date(state.monitor.next_due_at).toLocaleString(zh ? "zh-CN" : "en-US") : (zh ? "未排期" : "Unscheduled")}
{zh ? "上次检查:" : "Last check: "}{state.monitor.last_checked_at ? new Date(state.monitor.last_checked_at).toLocaleString() : (zh ? "尚未完成首次检查" : "No completed check yet")}
{zh ? "为当前管家准备一个可见的 LoopX 工作身份,保留原对话和权限。此步骤不会启动定时任务或模型。" : "Prepare one visible LoopX identity for this steward, retaining its original conversation and permissions. This step starts neither scheduled tasks nor a model."}
-{zh ? "汇报状态暂不可读;原计划和回执已保留。刷新连接后重试。" : "Report status is unavailable. The original schedule and receipts are retained; refresh the connection."}
: <> -{state.enabled ? (zh ? "已启用 · 完整中文正文回此私聊" : "Enabled · Full Chinese report returns to this private Chat") +
{!executionAvailable ? (zh ? "原汇报计划已保留,当前无法运行。" : "Original report configuration retained; execution unavailable.") + : state.enabled ? (zh ? "已启用 · 完整中文正文回此私聊" : "Enabled · Full Chinese report returns to this private Chat") : state.configured ? (zh ? "已暂停 · 原窗口和回执保留" : "Paused · Original windows and receipts retained") : (zh ? "尚未启用" : "Not enabled")}
-{zh ? "汇总全部获准本机 Goal,包括停止项和读取缺口。每天汇报前24小时,生成与实际送达分别核验;状态监控照常运行。" : "Covers every authorized local Goal, including stopped Goals and read gaps. Daily reports cover the previous 24 hours; generation and delivery are verified separately. Monitoring continues."}
+{zh ? "汇总全部获准本机 Goal,包括停止项和读取缺口。每天汇报前24小时,生成与实际送达分别核验;监控与汇报分别配置。" : "Covers every authorized local Goal, including stopped Goals and read gaps. Daily reports cover the previous 24 hours; generation and delivery are verified separately. Monitoring and reports are configured separately."}
{state.configured ?{zh ? "下次日历计划:" : "Next calendar deadline: "}{stamp(state.next_due_at)} Miww_jk7zy4MU@f+)FU9Htc@V5-YW
zMeA4o9cf|2%TNd|WdLNG^PRtam?WGnp>D$!iwNuGYG&@NjN;3FAY)_JvK%XSfEs8+
zccuUR-OJ~qCvc
{zh ? "最近窗口:" : "Latest window: "}{stamp(state.retained_window_due_at)} · {state.delivery_status === "delivered"
? (zh ? "原私聊全文已核验送达" : "Full private reply verified")
diff --git a/docs/assets/personal-workspace/steward-reports/retained-executor-before.png b/docs/assets/personal-workspace/steward-reports/retained-executor-before.png
new file mode 100644
index 0000000000000000000000000000000000000000..ecde975245b96c5878ba9fe821d2592ef7851ec5
GIT binary patch
literal 113721
zcmd?RWmHxD7d2`S2auMOIy8u=bR&mWNl{QrLIFVvGzM%3`iH^|;vY)j$w0sYh3e}&lfF;_
zBgHLDV~(L=>|-vOf%G5=IR`>rTBG&)J?B*&A;A~<1pFrDVAJqd{7aqRXnaZ#t_efI
zkLn`vLLOqxoM=h6JLj#qbX<#W3)2Z(h{Fr2Xa}7Ty3`^N91-X-))^2}X_~stA26o8
zhGSP73dstnKOk|X7NVwbIZnCl27YSXacnZ(KF~S5@cc5cC3LM>x+fXO!4Lv^G-@mu
z7KMU&$50S!*AeJxnn89c?*J#G!k8Ya`p&NwoRyy-k^X}pvs1anBK=K(;{wnTh
@xQik*R)E(W4}F*wbSG=N>nM{9i2wCW
zpErJS^#kZzYhN=Fs~~jGrM7hejz#oW0&$md
zKo0?)^rx26P@nkV&f!5yy)
M&
zC461@~g%u^1Tpp`Iy0(i-D$z|>x{>I;o(Sg|R9wq_bjG9s733#co8Z5
YdchJKC*1!cvQ>#(MoQ11BGOiCv~`p)kxpWG
z-_>%fOYWv>bsbT_T>BH%``YJ$?R+ZN>(U5gwS9HdtvMcIcWN!cbb|>7YJR}4-LDQQ
zXuv4+0+ZsNVNZq&I{}X?t^7>Pc)0f|>tvB)Rl-uDAK|Yw$|w7&C#Ow50Arc+4zzg$
zRqDHsuU-=ndNv=cpGRWH@aA2Kn&_mczUVxXu