feat(FN-4076): tighten mobile agents header and popup, add compact planning
Merges FN-4076: tightens the mobile Agents header and aligns the controls popup on smaller screens, while also introducing compact planning breakdown task creation with preserved payload coverage — tests for scoped and empty-generated planning payloads were added alongside fixes to the legacy API an Fusion-Task-Id: FN-4076
This commit is contained in:
@@ -16,6 +16,7 @@ import type {
|
||||
PlanningQuestion,
|
||||
PlanningSummary,
|
||||
PlanningResponse,
|
||||
TaskPriority,
|
||||
TaskStore,
|
||||
NtfyNotificationEvent,
|
||||
} from "@fusion/core";
|
||||
@@ -2234,6 +2235,15 @@ function buildPlanningSubtaskDescription(input: {
|
||||
return `${input.taskGuidance}\n\n${contextSections.join("\n\n")}`;
|
||||
}
|
||||
|
||||
export interface PlanningSubtaskDraft {
|
||||
id: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
suggestedSize?: "S" | "M" | "L";
|
||||
priority?: TaskPriority;
|
||||
dependsOn?: string[];
|
||||
}
|
||||
|
||||
export function generateSubtasksFromPlanning(sessionId: string): SubtaskItem[] {
|
||||
const session = sessions.get(sessionId);
|
||||
if (!session) return [];
|
||||
@@ -2303,6 +2313,51 @@ export function generateSubtasksFromPlanning(sessionId: string): SubtaskItem[] {
|
||||
];
|
||||
}
|
||||
|
||||
export function mergePlanningSubtaskDrafts(
|
||||
sessionId: string,
|
||||
drafts: PlanningSubtaskDraft[],
|
||||
): SubtaskItem[] {
|
||||
const generatedSubtasks = generateSubtasksFromPlanning(sessionId);
|
||||
const generatedById = new Map(generatedSubtasks.map((subtask) => [subtask.id, subtask]));
|
||||
|
||||
return drafts.map((draft) => {
|
||||
const generated = generatedById.get(draft.id);
|
||||
const normalizedDependsOn = Array.isArray(draft.dependsOn)
|
||||
? draft.dependsOn.filter((dependency): dependency is string => typeof dependency === "string")
|
||||
: undefined;
|
||||
|
||||
if (!generated) {
|
||||
const title = typeof draft.title === "string" ? draft.title.trim() : "";
|
||||
if (!title) {
|
||||
throw new Error(`Client-added subtask must have a title: ${draft.id}`);
|
||||
}
|
||||
|
||||
const description = typeof draft.description === "string" ? draft.description : title;
|
||||
return {
|
||||
id: draft.id,
|
||||
title,
|
||||
description,
|
||||
suggestedSize: draft.suggestedSize === "S" || draft.suggestedSize === "M" || draft.suggestedSize === "L"
|
||||
? draft.suggestedSize
|
||||
: "M",
|
||||
priority: draft.priority ?? DEFAULT_TASK_PRIORITY,
|
||||
dependsOn: normalizedDependsOn ?? [],
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
id: generated.id,
|
||||
title: typeof draft.title === "string" ? draft.title : generated.title,
|
||||
description: typeof draft.description === "string" ? draft.description : generated.description,
|
||||
suggestedSize: draft.suggestedSize === "S" || draft.suggestedSize === "M" || draft.suggestedSize === "L"
|
||||
? draft.suggestedSize
|
||||
: generated.suggestedSize,
|
||||
priority: draft.priority ?? generated.priority ?? DEFAULT_TASK_PRIORITY,
|
||||
dependsOn: normalizedDependsOn ?? generated.dependsOn,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup a session (used after task creation).
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user