Files
tutti/packages/agent/gui/agent-gui/agentGuiNode/controller/agentGuiController.providerHelpers.spec.ts
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

224 lines
6.2 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type {
AgentActivityComposerOptions,
AgentActivitySnapshot
} from "@tutti-os/agent-activity-core";
import {
composerOptionsForTarget,
composerOptionsLoadingForTarget,
ownerDeviceLabelForConversation,
resolveAgentGUIProviderRailTargetSelection,
targetConnectionForAgentGUIView
} from "./agentGuiController.providerHelpers";
import { createSharedAgentGUIAgentTarget } from "../../../agentTargets";
import type { AgentGUIComposerTargetData } from "./agentGuiController.composerPresentation";
import type { AgentGUIConversationSummary } from "../model/agentGuiConversationModel";
const target = {
agentTargetId: "target-1"
} as AgentGUIComposerTargetData;
describe("composer options target state", () => {
it("reports loading only before the target has cached options", () => {
const loadingSnapshot = snapshot({
composerOptionsLoadStatusByTargetKey: { "target-1": "loading" }
});
expect(
composerOptionsLoadingForTarget({ snapshot: loadingSnapshot, target })
).toBe(true);
expect(
composerOptionsForTarget({ snapshot: loadingSnapshot, target })
).toBe(null);
const cachedOptions = {} as AgentActivityComposerOptions;
const refreshingSnapshot = snapshot({
composerOptionsByTargetKey: { "target-1": cachedOptions },
composerOptionsLoadStatusByTargetKey: { "target-1": "loading" }
});
expect(
composerOptionsLoadingForTarget({ snapshot: refreshingSnapshot, target })
).toBe(false);
expect(
composerOptionsForTarget({ snapshot: refreshingSnapshot, target })
).toBe(cachedOptions);
});
it("does not leave the target loading after a request error", () => {
expect(
composerOptionsLoadingForTarget({
snapshot: snapshot({
composerOptionsLoadStatusByTargetKey: { "target-1": "error" }
}),
target
})
).toBe(false);
});
});
describe("provider rail target selection", () => {
it("keeps an active conversation that belongs to the selected target", () => {
expect(
resolveAgentGUIProviderRailTargetSelection({
activeConversation: conversation(
"claude-session",
"local:claude-code",
"claude-code"
),
nextFilter: {
kind: "agentTarget",
agentTargetId: "local:claude-code"
}
})
).toBe("keep-active-conversation");
});
it("opens the selected target home when the active conversation belongs elsewhere", () => {
expect(
resolveAgentGUIProviderRailTargetSelection({
activeConversation: conversation(
"codex-session",
"local:codex",
"codex"
),
nextFilter: {
kind: "agentTarget",
agentTargetId: "local:claude-code"
}
})
).toBe("open-home-composer");
});
it("opens the selected target home when there is no active conversation", () => {
expect(
resolveAgentGUIProviderRailTargetSelection({
activeConversation: null,
nextFilter: {
kind: "agentTarget",
agentTargetId: "local:claude-code"
}
})
).toBe("open-home-composer");
});
it("opens the selected target home when it has no agent target id", () => {
expect(
resolveAgentGUIProviderRailTargetSelection({
activeConversation: conversation(
"codex-session",
"local:codex",
"codex"
),
nextFilter: { kind: "all" }
})
).toBe("open-home-composer");
});
});
describe("conversation owner device label", () => {
it("uses the exact active conversation target instead of the selected composer target", () => {
const deviceA = createSharedAgentGUIAgentTarget({
agentTargetId: "target-a",
label: "Shared A",
ownerDeviceLabel: "Device A",
provider: "codex",
sharedAgentId: "shared-a"
});
const deviceB = createSharedAgentGUIAgentTarget({
agentTargetId: "target-b",
label: "Shared B",
ownerDeviceLabel: "Device B",
provider: "codex",
sharedAgentId: "shared-b"
});
expect(
ownerDeviceLabelForConversation(
conversation("session-b", "target-b", "codex"),
[deviceA, deviceB]
)
).toBe("Device B");
});
it("fails closed when the active conversation target is unavailable", () => {
expect(
ownerDeviceLabelForConversation(
conversation("session-b", "missing", "codex"),
[
createSharedAgentGUIAgentTarget({
agentTargetId: "target-a",
label: "Shared A",
ownerDeviceLabel: "Device A",
provider: "codex",
sharedAgentId: "shared-a"
})
]
)
).toBeNull();
});
});
describe("target connection selection", () => {
const selectedTarget = createSharedAgentGUIAgentTarget({
agentTargetId: "target-home",
label: "Shared Home",
ownerDeviceLabel: "Home Device",
provider: "codex",
sharedAgentId: "shared-home"
});
it("uses the selected Home target before a Session exists", () => {
expect(
targetConnectionForAgentGUIView({
activeConversation: null,
selectedTarget,
targets: [selectedTarget]
})
).toEqual({
agentTargetId: "target-home",
ownerDeviceLabel: "Home Device"
});
});
it("preserves the exact Session target when its presentation is stale", () => {
expect(
targetConnectionForAgentGUIView({
activeConversation: conversation(
"session-1",
"target-missing",
"codex"
),
selectedTarget,
targets: [selectedTarget]
})
).toEqual({ agentTargetId: "target-missing", ownerDeviceLabel: null });
});
});
function snapshot(
overrides: Partial<AgentActivitySnapshot>
): AgentActivitySnapshot {
return {
workspaceId: "workspace-1",
sessions: [],
presences: [],
sessionMessagesById: {},
...overrides
};
}
function conversation(
id: string,
agentTargetId: string,
provider: AgentGUIConversationSummary["provider"]
): AgentGUIConversationSummary {
return {
id,
agentTargetId,
cwd: "/repo",
provider,
status: "completed",
title: id,
updatedAtUnixMs: 1
};
}