Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

161 lines
4.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
effectiveTaskAssignmentValue,
effectiveTaskFlag,
mergeTaskAssignmentDraft,
taskAssignmentInputsFromDrafts
} from "./tuttiModePlanTaskAssignments";
import type { TuttiModePlanPanelTaskViewModel } from "./tuttiModePlanPanelProjection";
function taskViewModel(
overrides: Partial<TuttiModePlanPanelTaskViewModel> & { id: string }
): TuttiModePlanPanelTaskViewModel {
return {
ordinal: 1,
title: "Task",
content: "",
priority: "medium",
agentTargetId: null,
modelPlanId: null,
model: null,
permissionModeId: null,
reasoningEffort: null,
executionDirectory: null,
dependsOn: [],
parallelizable: false,
autoAccept: false,
...overrides
};
}
describe("mergeTaskAssignmentDraft", () => {
it("stores field edits per task", () => {
const drafts = mergeTaskAssignmentDraft({}, "task-1", {
reasoningEffort: "high"
});
expect(drafts["task-1"]).toEqual({ reasoningEffort: "high" });
});
it("resets dependent selections when the agent changes", () => {
let drafts = mergeTaskAssignmentDraft({}, "task-1", {
modelPlanId: "plan-1",
model: "model-1"
});
drafts = mergeTaskAssignmentDraft(drafts, "task-1", {
agentTargetId: "agent-2"
});
expect(drafts["task-1"]).toEqual({
agentTargetId: "agent-2",
modelPlanId: "",
model: "",
permissionModeId: "",
reasoningEffort: ""
});
});
it("keeps the agent-independent toggles across agent changes", () => {
let drafts = mergeTaskAssignmentDraft({}, "task-1", {
parallelizable: true
});
drafts = mergeTaskAssignmentDraft(drafts, "task-1", { autoAccept: true });
drafts = mergeTaskAssignmentDraft(drafts, "task-1", {
agentTargetId: "agent-2"
});
expect(drafts["task-1"]).toEqual({
agentTargetId: "agent-2",
modelPlanId: "",
model: "",
permissionModeId: "",
reasoningEffort: "",
parallelizable: true,
autoAccept: true
});
expect(effectiveTaskFlag(undefined, true)).toBe(true);
expect(effectiveTaskFlag(false, true)).toBe(false);
const inputs = taskAssignmentInputsFromDrafts(drafts, [
taskViewModel({ id: "task-1" })
]);
expect(inputs).toEqual([
{
taskId: "task-1",
agentTargetId: "agent-2",
modelPlanId: "",
model: "",
permissionModeId: "",
reasoningEffort: "",
parallelizable: true,
autoAccept: true
}
]);
});
it("keeps other fields when the same agent is re-selected", () => {
let drafts = mergeTaskAssignmentDraft({}, "task-1", {
agentTargetId: "agent-1"
});
drafts = mergeTaskAssignmentDraft(drafts, "task-1", { model: "model-9" });
drafts = mergeTaskAssignmentDraft(drafts, "task-1", {
agentTargetId: "agent-1"
});
expect(drafts["task-1"]?.model).toBe("model-9");
});
});
describe("effectiveTaskAssignmentValue", () => {
it("prefers the draft edit, including an explicit clear", () => {
expect(effectiveTaskAssignmentValue(undefined, "doc-value")).toBe(
"doc-value"
);
expect(effectiveTaskAssignmentValue("edit", "doc-value")).toBe("edit");
expect(effectiveTaskAssignmentValue("", "doc-value")).toBe("");
expect(effectiveTaskAssignmentValue(undefined, null)).toBe("");
});
});
describe("taskAssignmentInputsFromDrafts", () => {
it("sends only touched tasks and touched fields", () => {
const tasks = [
taskViewModel({ id: "task-1" }),
taskViewModel({ id: "task-2", ordinal: 2 })
];
const drafts = mergeTaskAssignmentDraft({}, "task-2", {
reasoningEffort: "high"
});
const inputs = taskAssignmentInputsFromDrafts(drafts, tasks);
expect(inputs).toEqual([{ taskId: "task-2", reasoningEffort: "high" }]);
expect("model" in inputs[0]!).toBe(false);
});
it("carries the dependent clears produced by an agent change", () => {
const tasks = [taskViewModel({ id: "task-1" })];
const drafts = mergeTaskAssignmentDraft({}, "task-1", {
agentTargetId: "agent-1"
});
expect(taskAssignmentInputsFromDrafts(drafts, tasks)).toEqual([
{
taskId: "task-1",
agentTargetId: "agent-1",
modelPlanId: "",
model: "",
permissionModeId: "",
reasoningEffort: ""
}
]);
});
it("drops drafts for tasks missing from the current revision", () => {
const drafts = mergeTaskAssignmentDraft({}, "task-gone", {
model: "model-1"
});
expect(
taskAssignmentInputsFromDrafts(drafts, [taskViewModel({ id: "task-1" })])
).toEqual([]);
});
it("returns an empty payload for untouched drafts", () => {
expect(
taskAssignmentInputsFromDrafts({}, [taskViewModel({ id: "task-1" })])
).toEqual([]);
});
});