refactor: keep imported project understanding sync automatic
This commit is contained in:
@@ -677,7 +677,7 @@ export interface MasterAgentTask {
|
||||
deviceImportCandidateId?: string;
|
||||
deviceImportCandidateFolderName?: string;
|
||||
projectUnderstandingTargetProjectId?: string;
|
||||
projectUnderstandingReason?: "heartbeat_activity" | "thread_reply" | "manual_device_sync";
|
||||
projectUnderstandingReason?: "heartbeat_activity" | "thread_reply";
|
||||
status: MasterAgentTaskStatus;
|
||||
requestedAt: string;
|
||||
claimedAt?: string;
|
||||
@@ -2995,9 +2995,7 @@ function normalizeState(raw: Partial<BossState> | undefined): BossState {
|
||||
deviceImportCandidateFolderName: task.deviceImportCandidateFolderName,
|
||||
projectUnderstandingTargetProjectId: task.projectUnderstandingTargetProjectId,
|
||||
projectUnderstandingReason:
|
||||
task.projectUnderstandingReason === "heartbeat_activity" ||
|
||||
task.projectUnderstandingReason === "thread_reply" ||
|
||||
task.projectUnderstandingReason === "manual_device_sync"
|
||||
task.projectUnderstandingReason === "heartbeat_activity" || task.projectUnderstandingReason === "thread_reply"
|
||||
? task.projectUnderstandingReason
|
||||
: undefined,
|
||||
status: task.status ?? "queued",
|
||||
@@ -5207,7 +5205,7 @@ export async function queueMasterAgentTask(payload: {
|
||||
deviceImportCandidateId?: string;
|
||||
deviceImportCandidateFolderName?: string;
|
||||
projectUnderstandingTargetProjectId?: string;
|
||||
projectUnderstandingReason?: "heartbeat_activity" | "thread_reply" | "manual_device_sync";
|
||||
projectUnderstandingReason?: "heartbeat_activity" | "thread_reply";
|
||||
}) {
|
||||
const task = await mutateState((state) => {
|
||||
const task: MasterAgentTask = {
|
||||
@@ -7356,12 +7354,7 @@ function applyProjectUnderstandingSnapshotInState(
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
function shouldQueueProjectUnderstandingSync(
|
||||
project: Project,
|
||||
observedActivityAt: string,
|
||||
state: BossState,
|
||||
options?: { force?: boolean },
|
||||
) {
|
||||
function shouldQueueProjectUnderstandingSync(project: Project, observedActivityAt: string, state: BossState) {
|
||||
if (!isDispatchableThreadProject(project)) {
|
||||
return false;
|
||||
}
|
||||
@@ -7369,16 +7362,14 @@ function shouldQueueProjectUnderstandingSync(
|
||||
if (!Number.isFinite(observedTs)) {
|
||||
return false;
|
||||
}
|
||||
if (!options?.force) {
|
||||
const latestWatermark = Date.parse(
|
||||
project.threadMeta.lastProjectUnderstandingRequestedAt ??
|
||||
project.threadMeta.lastProjectUnderstandingSyncedAt ??
|
||||
project.projectUnderstanding?.updatedAt ??
|
||||
"1970-01-01T00:00:00.000Z",
|
||||
);
|
||||
if (Number.isFinite(latestWatermark) && observedTs <= latestWatermark) {
|
||||
return false;
|
||||
}
|
||||
const latestWatermark = Date.parse(
|
||||
project.threadMeta.lastProjectUnderstandingRequestedAt ??
|
||||
project.threadMeta.lastProjectUnderstandingSyncedAt ??
|
||||
project.projectUnderstanding?.updatedAt ??
|
||||
"1970-01-01T00:00:00.000Z",
|
||||
);
|
||||
if (Number.isFinite(latestWatermark) && observedTs <= latestWatermark) {
|
||||
return false;
|
||||
}
|
||||
return !state.masterAgentTasks.some(
|
||||
(task) =>
|
||||
@@ -7389,22 +7380,13 @@ function shouldQueueProjectUnderstandingSync(
|
||||
);
|
||||
}
|
||||
|
||||
function buildProjectUnderstandingSyncPrompt(
|
||||
project: Project,
|
||||
reason: "heartbeat_activity" | "thread_reply" | "manual_device_sync",
|
||||
) {
|
||||
function buildProjectUnderstandingSyncPrompt(project: Project, reason: "heartbeat_activity" | "thread_reply") {
|
||||
return [
|
||||
"你正在向主 Agent 同步当前项目状态。",
|
||||
`项目名称:${project.name}`,
|
||||
`线程名称:${project.threadMeta.threadDisplayName}`,
|
||||
`文件夹:${project.threadMeta.folderName}`,
|
||||
`同步原因:${
|
||||
reason === "heartbeat_activity"
|
||||
? "检测到线程有新活动"
|
||||
: reason === "thread_reply"
|
||||
? "线程刚刚产生了新的执行结果"
|
||||
: "用户主动要求同步当前设备上的活跃项目理解"
|
||||
}`,
|
||||
`同步原因:${reason === "heartbeat_activity" ? "检测到线程有新活动" : "线程刚刚产生了新的执行结果"}`,
|
||||
"",
|
||||
"只输出 JSON,不要输出解释性文字或 Markdown。",
|
||||
"JSON 结构固定为:",
|
||||
@@ -7420,17 +7402,14 @@ function buildProjectUnderstandingSyncPrompt(
|
||||
async function queueProjectUnderstandingSyncTask(input: {
|
||||
projectId: string;
|
||||
observedActivityAt: string;
|
||||
reason: "heartbeat_activity" | "thread_reply" | "manual_device_sync";
|
||||
force?: boolean;
|
||||
requestedByAccount?: string;
|
||||
reason: "heartbeat_activity" | "thread_reply";
|
||||
}) {
|
||||
const state = await readState();
|
||||
const project = state.projects.find((item) => item.id === input.projectId);
|
||||
if (!project || !shouldQueueProjectUnderstandingSync(project, input.observedActivityAt, state, { force: input.force })) {
|
||||
if (!project || !shouldQueueProjectUnderstandingSync(project, input.observedActivityAt, state)) {
|
||||
return null;
|
||||
}
|
||||
const requestedByAccount =
|
||||
input.requestedByAccount?.trim() || state.user.account || project.deviceIds[0] || "17600003315";
|
||||
const requestedByAccount = state.user.account || project.deviceIds[0] || "17600003315";
|
||||
const task = await queueMasterAgentTask({
|
||||
projectId: "master-agent",
|
||||
taskType: "conversation_reply",
|
||||
@@ -7463,82 +7442,6 @@ async function queueProjectUnderstandingSyncTask(input: {
|
||||
return task;
|
||||
}
|
||||
|
||||
export async function syncDeviceProjectUnderstanding(input: {
|
||||
deviceId: string;
|
||||
requestedByAccount: string;
|
||||
limit?: number;
|
||||
}) {
|
||||
const state = await readState();
|
||||
const device = state.devices.find((item) => item.id === input.deviceId);
|
||||
if (!device) {
|
||||
throw new Error("DEVICE_NOT_FOUND");
|
||||
}
|
||||
|
||||
const activeProjects = state.projects
|
||||
.filter(
|
||||
(project) =>
|
||||
!project.isGroup &&
|
||||
project.deviceIds.includes(input.deviceId) &&
|
||||
isDispatchableThreadProject(project) &&
|
||||
Boolean(project.threadMeta.codexThreadRef?.trim()),
|
||||
)
|
||||
.sort((left, right) =>
|
||||
String(
|
||||
right.threadMeta.lastObservedCodexActivityAt ??
|
||||
right.projectUnderstanding?.updatedAt ??
|
||||
right.lastMessageAt,
|
||||
).localeCompare(
|
||||
String(
|
||||
left.threadMeta.lastObservedCodexActivityAt ??
|
||||
left.projectUnderstanding?.updatedAt ??
|
||||
left.lastMessageAt,
|
||||
),
|
||||
),
|
||||
)
|
||||
.slice(0, Math.max(1, input.limit ?? 3));
|
||||
|
||||
const queuedTasks = [];
|
||||
for (const project of activeProjects) {
|
||||
const observedActivityAt =
|
||||
project.threadMeta.lastObservedCodexActivityAt ??
|
||||
project.projectUnderstanding?.updatedAt ??
|
||||
project.lastMessageAt ??
|
||||
nowIso();
|
||||
const task = await queueProjectUnderstandingSyncTask({
|
||||
projectId: project.id,
|
||||
observedActivityAt,
|
||||
reason: "manual_device_sync",
|
||||
force: true,
|
||||
requestedByAccount: input.requestedByAccount,
|
||||
});
|
||||
if (task) {
|
||||
queuedTasks.push({
|
||||
taskId: task.taskId,
|
||||
projectId: project.id,
|
||||
projectName: project.name,
|
||||
threadDisplayName: project.threadMeta.threadDisplayName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ok: true as const,
|
||||
deviceId: device.id,
|
||||
deviceName: device.name,
|
||||
queuedTasks,
|
||||
activeProjects: activeProjects.map((project) => ({
|
||||
projectId: project.id,
|
||||
projectName: project.name,
|
||||
threadDisplayName: project.threadMeta.threadDisplayName,
|
||||
lastObservedCodexActivityAt:
|
||||
project.threadMeta.lastObservedCodexActivityAt ??
|
||||
project.projectUnderstanding?.updatedAt ??
|
||||
project.lastMessageAt,
|
||||
currentProgress: project.projectUnderstanding?.currentProgress ?? "",
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export async function previewDeviceImportResolution(input: { deviceId: string }) {
|
||||
const state = await readState();
|
||||
const draft = state.deviceImportDrafts.find((item) => item.deviceId === input.deviceId);
|
||||
|
||||
Reference in New Issue
Block a user