From 28f692706b03415016ca49977744d519f18f7ccb Mon Sep 17 00:00:00 2001 From: kris Date: Sun, 5 Apr 2026 07:53:03 +0800 Subject: [PATCH] refactor: remove stale import understanding surfaces --- .../hyzq/boss/DeviceImportDraftActivity.java | 60 ++---------- .../boss/DeviceImportDraftActivityTest.java | 40 ++------ src/lib/boss-data.ts | 95 +------------------ src/lib/boss-master-agent.ts | 8 -- 4 files changed, 13 insertions(+), 190 deletions(-) diff --git a/android/app/src/main/java/com/hyzq/boss/DeviceImportDraftActivity.java b/android/app/src/main/java/com/hyzq/boss/DeviceImportDraftActivity.java index 74df1fd..1c776d2 100644 --- a/android/app/src/main/java/com/hyzq/boss/DeviceImportDraftActivity.java +++ b/android/app/src/main/java/com/hyzq/boss/DeviceImportDraftActivity.java @@ -24,8 +24,6 @@ public class DeviceImportDraftActivity extends BossScreenActivity { private @Nullable JSONObject currentDraft; private @Nullable JSONObject currentResolution; private @Nullable JSONObject currentReviewTask; - private @Nullable JSONArray currentUnderstandingTasks; - private @Nullable JSONArray currentProjectUnderstandings; private final LinkedHashSet selectedCandidateIds = new LinkedHashSet<>(); private final Runnable reviewPollRunnable = this::reload; @@ -55,9 +53,7 @@ public class DeviceImportDraftActivity extends BossScreenActivity { runOnUiThread(() -> applyPayload( response.json.optJSONObject("draft"), response.json.optJSONObject("resolution"), - response.json.optJSONObject("reviewTask"), - response.json.optJSONArray("understandingTasks"), - response.json.optJSONArray("projectUnderstandings") + response.json.optJSONObject("reviewTask") )); } catch (Exception error) { runOnUiThread(() -> { @@ -71,15 +67,11 @@ public class DeviceImportDraftActivity extends BossScreenActivity { private void applyPayload( @Nullable JSONObject draft, @Nullable JSONObject resolution, - @Nullable JSONObject reviewTask, - @Nullable JSONArray understandingTasks, - @Nullable JSONArray projectUnderstandings + @Nullable JSONObject reviewTask ) { currentDraft = draft; currentResolution = resolution; currentReviewTask = reviewTask; - currentUnderstandingTasks = understandingTasks; - currentProjectUnderstandings = projectUnderstandings; selectedCandidateIds.clear(); JSONArray selected = draft == null ? null : draft.optJSONArray("selectedCandidateIds"); if (selected != null) { @@ -117,8 +109,6 @@ public class DeviceImportDraftActivity extends BossScreenActivity { JSONObject draft = currentDraft; JSONObject resolution = currentResolution; JSONObject reviewTask = currentReviewTask; - JSONArray understandingTasks = currentUnderstandingTasks; - JSONArray projectUnderstandings = currentProjectUnderstandings; contentLayout.removeCallbacks(reviewPollRunnable); replaceContent(); appendContent(BossUi.buildSoftPanel( @@ -237,40 +227,6 @@ public class DeviceImportDraftActivity extends BossScreenActivity { )); } - if (understandingTasks != null && understandingTasks.length() > 0) { - int completedCount = 0; - for (int i = 0; i < understandingTasks.length(); i++) { - JSONObject task = understandingTasks.optJSONObject(i); - if (task != null && "completed".equals(task.optString("status", ""))) { - completedCount += 1; - } - } - appendContent(BossUi.buildCard( - this, - "项目理解", - completedCount == understandingTasks.length() - ? "主 Agent 已经拿到活跃线程的项目目标、进度和技术架构。" - : "主 Agent 正在向活跃线程追问项目目标、进度和技术架构。", - "已完成 " + completedCount + " / " + understandingTasks.length() - )); - } - - if (projectUnderstandings != null) { - for (int i = 0; i < projectUnderstandings.length(); i++) { - JSONObject understanding = projectUnderstandings.optJSONObject(i); - if (understanding == null) continue; - appendContent(BossUi.buildCard( - this, - understanding.optString("threadDisplayName", "项目理解"), - "目标:" + understanding.optString("projectGoal", "未提供") - + "\n进度:" + understanding.optString("currentProgress", "未提供") - + "\n架构:" + understanding.optString("technicalArchitecture", "未提供"), - "阻塞:" + understanding.optString("currentBlockers", "无") - + " · 下一步:" + understanding.optString("recommendedNextStep", "继续联调") - )); - } - } - JSONArray appliedProjectNames = draft.optJSONArray("appliedProjectNames"); if (appliedProjectNames != null && appliedProjectNames.length() > 0) { appendContent(BossUi.buildCard( @@ -417,16 +373,14 @@ public class DeviceImportDraftActivity extends BossScreenActivity { reviewResponse.json.optJSONObject("resolution"), reviewResponse.json.optJSONObject("reviewTask") != null ? reviewResponse.json.optJSONObject("reviewTask") - : reviewResponse.json.optJSONObject("task"), - reviewResponse.json.optJSONArray("understandingTasks"), - reviewResponse.json.optJSONArray("projectUnderstandings") + : reviewResponse.json.optJSONObject("task") ); }); } catch (Exception error) { final JSONObject fallbackDraft = selectedDraft; runOnUiThread(() -> { if (fallbackDraft != null) { - applyPayload(fallbackDraft, null, null, null, null); + applyPayload(fallbackDraft, null, null); } else { setRefreshing(false); } @@ -450,7 +404,7 @@ public class DeviceImportDraftActivity extends BossScreenActivity { } runOnUiThread(() -> { showMessage("已清空当前勾选"); - applyPayload(response.json.optJSONObject("draft"), null, null, null, null); + applyPayload(response.json.optJSONObject("draft"), null, null); }); } catch (Exception error) { runOnUiThread(() -> { @@ -478,9 +432,7 @@ public class DeviceImportDraftActivity extends BossScreenActivity { applyPayload( response.json.optJSONObject("draft"), response.json.optJSONObject("resolution"), - null, - null, - response.json.optJSONArray("projectUnderstandings") + null ); }); } catch (Exception error) { diff --git a/android/app/src/test/java/com/hyzq/boss/DeviceImportDraftActivityTest.java b/android/app/src/test/java/com/hyzq/boss/DeviceImportDraftActivityTest.java index a54c998..971eba0 100644 --- a/android/app/src/test/java/com/hyzq/boss/DeviceImportDraftActivityTest.java +++ b/android/app/src/test/java/com/hyzq/boss/DeviceImportDraftActivityTest.java @@ -37,9 +37,7 @@ public class DeviceImportDraftActivityTest { "applyPayload", ReflectionHelpers.ClassParameter.from(JSONObject.class, buildPendingDraft()), ReflectionHelpers.ClassParameter.from(JSONObject.class, null), - ReflectionHelpers.ClassParameter.from(JSONObject.class, null), - ReflectionHelpers.ClassParameter.from(JSONArray.class, null), - ReflectionHelpers.ClassParameter.from(JSONArray.class, null) + ReflectionHelpers.ClassParameter.from(JSONObject.class, null) ); View content = activity.findViewById(R.id.screen_content); @@ -66,9 +64,7 @@ public class DeviceImportDraftActivityTest { "applyPayload", ReflectionHelpers.ClassParameter.from(JSONObject.class, buildAppliedDraft()), ReflectionHelpers.ClassParameter.from(JSONObject.class, buildAppliedResolution()), - ReflectionHelpers.ClassParameter.from(JSONObject.class, null), - ReflectionHelpers.ClassParameter.from(JSONArray.class, null), - ReflectionHelpers.ClassParameter.from(JSONArray.class, null) + ReflectionHelpers.ClassParameter.from(JSONObject.class, null) ); View content = activity.findViewById(R.id.screen_content); @@ -80,7 +76,7 @@ public class DeviceImportDraftActivityTest { } @Test - public void renderCurrentStateShowsQueuedReviewTaskCopy() throws Exception { + public void renderCurrentStateShowsQueuedReviewTaskCopyWithoutProjectUnderstandingSection() throws Exception { TestDeviceImportDraftActivity activity = Robolectric .buildActivity( TestDeviceImportDraftActivity.class, @@ -96,18 +92,15 @@ public class DeviceImportDraftActivityTest { "applyPayload", ReflectionHelpers.ClassParameter.from(JSONObject.class, buildPendingResolutionDraft()), ReflectionHelpers.ClassParameter.from(JSONObject.class, null), - ReflectionHelpers.ClassParameter.from(JSONObject.class, buildQueuedReviewTask()), - ReflectionHelpers.ClassParameter.from(JSONArray.class, buildUnderstandingTasks()), - ReflectionHelpers.ClassParameter.from(JSONArray.class, buildProjectUnderstandings()) + ReflectionHelpers.ClassParameter.from(JSONObject.class, buildQueuedReviewTask()) ); View content = activity.findViewById(R.id.screen_content); assertTrue(viewTreeContainsText(content, "主 Agent 审核中")); assertTrue(viewTreeContainsText(content, "审核任务")); assertTrue(viewTreeContainsText(content, "状态:queued")); - assertTrue(viewTreeContainsText(content, "项目理解")); - assertTrue(viewTreeContainsText(content, "北区试产线回归")); - assertTrue(viewTreeContainsText(content, "树莓派二代接入与联调")); + assertFalse(viewTreeContainsText(content, "项目理解")); + assertFalse(viewTreeContainsText(content, "树莓派二代接入与联调")); } private static JSONObject buildPendingDraft() throws Exception { @@ -209,27 +202,6 @@ public class DeviceImportDraftActivityTest { .put("status", "queued"); } - private static JSONArray buildUnderstandingTasks() throws Exception { - return new JSONArray() - .put(new JSONObject() - .put("taskId", "mastertask-understanding-1") - .put("candidateId", "candidate-1") - .put("threadDisplayName", "北区试产线回归") - .put("status", "completed")); - } - - private static JSONArray buildProjectUnderstandings() throws Exception { - return new JSONArray() - .put(new JSONObject() - .put("candidateId", "candidate-1") - .put("threadDisplayName", "北区试产线回归") - .put("projectGoal", "完成树莓派二代接入与联调") - .put("currentProgress", "正在核对接线和控制链路") - .put("technicalArchitecture", "Next.js 控制台 + local-agent + Codex 线程") - .put("currentBlockers", "串口稳定性待验证") - .put("recommendedNextStep", "先确认串口日志")); - } - private static boolean viewTreeContainsText(View root, String expectedText) { if (root instanceof TextView) { CharSequence text = ((TextView) root).getText(); diff --git a/src/lib/boss-data.ts b/src/lib/boss-data.ts index 1ae1726..840970b 100644 --- a/src/lib/boss-data.ts +++ b/src/lib/boss-data.ts @@ -7332,55 +7332,7 @@ export async function getLatestDeviceImportDraft(deviceId: string) { item.deviceImportDraftId === draft.draftId, ) ?? null : null; - const understandingTasks = draft - ? listDeviceImportUnderstandingTasks(state, draft.draftId) - : []; - const projectUnderstandings = draft - ? deriveDeviceImportProjectUnderstandings(state, draft.draftId) - : []; - return { draft, resolution, reviewTask, understandingTasks, projectUnderstandings }; -} - -function listDeviceImportUnderstandingTasks(state: BossState, draftId: string) { - const latestByCandidate = new Map(); - for (const task of state.masterAgentTasks) { - if ( - task.taskType !== "conversation_reply" || - task.deviceImportDraftId !== draftId || - !task.deviceImportCandidateId - ) { - continue; - } - const existing = latestByCandidate.get(task.deviceImportCandidateId); - if (!existing || existing.requestedAt < task.requestedAt) { - latestByCandidate.set(task.deviceImportCandidateId, task); - } - } - return [...latestByCandidate.values()].map((task) => ({ - taskId: task.taskId, - candidateId: task.deviceImportCandidateId ?? "", - threadDisplayName: task.targetThreadDisplayName ?? "", - folderName: task.deviceImportCandidateFolderName ?? "", - status: task.status, - updatedAt: task.completedAt ?? task.claimedAt ?? task.requestedAt, - })); -} - -function parseDeviceImportUnderstandingReply( - task: Pick, -): DeviceImportProjectUnderstanding | null { - const understanding = parseStructuredProjectUnderstandingReply(task); - const candidateId = task.deviceImportCandidateId?.trim(); - if (!candidateId || !understanding) { - return null; - } - - return { - candidateId, - threadDisplayName: task.targetThreadDisplayName?.trim() || "未命名线程", - folderName: task.deviceImportCandidateFolderName?.trim() || "", - ...understanding, - }; + return { draft, resolution, reviewTask }; } function parseStructuredProjectUnderstandingReply( @@ -7429,29 +7381,6 @@ function parseStructuredProjectUnderstandingReply( }; } -function deriveDeviceImportProjectUnderstandings(state: BossState, draftId: string) { - const latestByCandidate = new Map(); - for (const task of state.masterAgentTasks) { - if ( - task.taskType !== "conversation_reply" || - task.deviceImportDraftId !== draftId || - task.status !== "completed" || - !task.deviceImportCandidateId - ) { - continue; - } - const understanding = parseDeviceImportUnderstandingReply(task); - if (!understanding) { - continue; - } - const existing = latestByCandidate.get(understanding.candidateId); - if (!existing || existing.updatedAt < understanding.updatedAt) { - latestByCandidate.set(understanding.candidateId, understanding); - } - } - return [...latestByCandidate.values()]; -} - function applyProjectUnderstandingSnapshotInState( state: BossState, input: { @@ -8085,9 +8014,6 @@ function applyDeviceImportResolutionInState( const selectedCandidates = draft.candidates.filter((candidate) => draft.selectedCandidateIds.includes(candidate.candidateId), ); - const understandingsByCandidate = new Map( - deriveDeviceImportProjectUnderstandings(state, draft.draftId).map((item) => [item.candidateId, item] as const), - ); const importedProjects: Project[] = []; for (const item of resolution.items) { const candidate = draft.candidates.find((entry) => entry.candidateId === item.candidateId); @@ -8132,25 +8058,6 @@ function applyDeviceImportResolutionInState( targetProject.preview = `已导入 ${candidate.threadDisplayName}`; targetProject.updatedAt = nowIso(); targetProject.lastMessageAt = targetProject.updatedAt; - const understanding = understandingsByCandidate.get(candidate.candidateId); - if (understanding) { - applyProjectUnderstandingSnapshotInState(state, { - projectId: targetProject.id, - account: device.account, - snapshot: { - projectGoal: understanding.projectGoal, - currentProgress: understanding.currentProgress, - technicalArchitecture: understanding.technicalArchitecture, - currentBlockers: understanding.currentBlockers, - recommendedNextStep: understanding.recommendedNextStep, - sourceTaskId: understanding.sourceTaskId, - updatedAt: understanding.updatedAt, - sourceKind: "device_import", - }, - sourceMessageId: understanding.sourceTaskId, - sourceKind: "device_import", - }); - } importedProjects.push({ ...targetProject }); } diff --git a/src/lib/boss-master-agent.ts b/src/lib/boss-master-agent.ts index 5818cc8..c025304 100644 --- a/src/lib/boss-master-agent.ts +++ b/src/lib/boss-master-agent.ts @@ -1795,7 +1795,6 @@ export async function queueDeviceImportResolutionTask(params: { const selectedCandidates = draft.candidates.filter((candidate) => draft.selectedCandidateIds.includes(candidate.candidateId), ); - const understandingTasks: Array>> = []; const task = await queueMasterAgentTask({ projectId: "master-agent", taskType: "device_import_resolution", @@ -1836,13 +1835,6 @@ export async function queueDeviceImportResolutionTask(params: { deviceImportDraftId: task.deviceImportDraftId, }, draft: latest.draft ?? undefined, - understandingTasks: understandingTasks.map((item) => ({ - taskId: item.taskId, - taskType: item.taskType, - status: item.status, - candidateId: item.deviceImportCandidateId, - threadDisplayName: item.targetThreadDisplayName, - })), ...(latest.resolution ? { resolution: latest.resolution } : {}), }; }