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

379 lines
11 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
agentGuiWorkbenchPrefillPromptActivationType,
agentGuiWorkbenchProviderFromLaunchRequest,
agentGuiWorkbenchUnifiedDockEntryId,
createAgentGuiWorkbenchDraftLaunchRequest,
createAgentGuiWorkbenchInstanceId,
createAgentGuiWorkbenchLaunchDescriptor,
createAgentGuiWorkbenchSessionLaunchRequest
} from "./launch.ts";
describe("agent gui workbench launch contract", () => {
it("keeps runtime instance ids opaque", () => {
expect(agentGuiWorkbenchUnifiedDockEntryId()).toBe("agent-gui:unified");
const first = createAgentGuiWorkbenchInstanceId();
const second = createAgentGuiWorkbenchInstanceId();
expect(first).toMatch(/^agent-gui:instance:/);
expect(second).toMatch(/^agent-gui:instance:/);
expect(first).not.toBe(second);
});
it("requires launch providers in payloads", () => {
expect(
agentGuiWorkbenchProviderFromLaunchRequest({
dockEntryId: "agent-gui:codex",
payload: { provider: "claude-code" },
typeId: "agent-gui"
})
).toBe("claude-code");
expect(() =>
agentGuiWorkbenchProviderFromLaunchRequest({
dockEntryId: "agent-gui:hermes",
payload: {},
typeId: "agent-gui"
})
).toThrow("agent_gui_workbench.launch_provider_required");
expect(() =>
agentGuiWorkbenchProviderFromLaunchRequest({
payload: null,
typeId: "agent-gui"
})
).toThrow("agent_gui_workbench.launch_provider_required");
});
it("uses the unified dock identity in launch descriptors", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: "agent-gui:claude-code",
payload: { provider: "codex" },
typeId: "agent-gui"
});
expect(descriptor.dockEntryId).toBe("agent-gui:unified");
expect(descriptor.instanceId).toMatch(/^agent-gui:instance:/);
expect(descriptor.provider).toBe("codex");
});
it("launches sessions into provider panels until current session state can reuse a node", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: "agent-gui:unified",
payload: {
agentSessionId: "session-2",
provider: "codex"
},
typeId: "agent-gui"
});
expect(descriptor).toMatchObject({
activation: {
payload: {
agentSessionId: "session-2"
},
type: "agent-gui:open-session"
},
dockEntryId: "agent-gui:unified",
openInNewWindow: false,
provider: "codex",
reusePolicy: {
agentSessionId: "session-2",
kind: "current-session"
},
targetAgentSessionId: "session-2"
});
expect(descriptor.instanceId).toMatch(/^agent-gui:instance:/);
});
it("launches sessions with target metadata into target panels", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: "agent-gui",
payload: {
agentSessionId: "session-2",
agentTargetId: "local:codex",
provider: "codex"
},
typeId: "agent-gui"
})
).toMatchObject({
openInNewWindow: false,
reusePolicy: {
agentSessionId: "session-2",
kind: "current-session"
},
targetAgentSessionId: "session-2"
});
});
it("can launch an existing session into a new internal window", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: "agent-gui:codex",
payload: {
agentSessionId: "session-2",
openInNewWindow: true,
provider: "codex"
},
typeId: "agent-gui"
});
expect(descriptor.activation).toEqual({
payload: {
agentSessionId: "session-2"
},
type: "agent-gui:open-session"
});
expect(descriptor.instanceId).toMatch(/^agent-gui:instance:/);
expect(descriptor.openInNewWindow).toBe(true);
expect(descriptor.reusePolicy).toEqual({ kind: "none" });
expect(descriptor.targetAgentSessionId).toBe("session-2");
});
it("keeps provider metadata separate from opaque aggregate instances", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
payload: {
provider: "claude-code"
},
typeId: "agent-gui"
});
expect(descriptor.dockEntryId).toBe("agent-gui:unified");
expect(descriptor.instanceId).toMatch(/^agent-gui:instance:/);
expect(descriptor.provider).toBe("claude-code");
expect(descriptor.reusePolicy).toEqual({ kind: "dock-entry" });
});
it("keeps a managed edit prompt attached to the exact source session", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor(
createAgentGuiWorkbenchSessionLaunchRequest({
agentSessionId: " source-session-9 ",
composerAppend: {
draftPrompt: " Modify the managed issue ",
focusComposer: true
},
provider: "codex"
})
);
expect(descriptor.activation).toEqual({
payload: {
agentSessionId: "source-session-9",
composerAppend: {
draftPrompt: "Modify the managed issue",
focusComposer: true
}
},
type: "agent-gui:open-session"
});
expect(descriptor.reusePolicy).toEqual({
agentSessionId: "source-session-9",
kind: "current-session"
});
});
it("reuses unified aggregate dock nodes for empty launches", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
payload: {
provider: "codex"
},
typeId: "agent-gui"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
openInNewWindow: false,
provider: "codex",
reusePolicy: { kind: "dock-entry" },
targetAgentSessionId: null
});
});
it("can force a new in-workspace instance without opening a new window", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor(
createAgentGuiWorkbenchSessionLaunchRequest({
forceNewInstance: true,
provider: "codex"
})
);
expect(descriptor.openInNewWindow).toBe(false);
expect(descriptor.reusePolicy).toEqual({ kind: "none" });
expect(descriptor.targetAgentSessionId).toBeNull();
});
it("does not reuse an existing session when a new instance is required", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor(
createAgentGuiWorkbenchSessionLaunchRequest({
agentSessionId: "session-replay",
forceNewInstance: true,
provider: "codex"
})
);
expect(descriptor.openInNewWindow).toBe(false);
expect(descriptor.reusePolicy).toEqual({ kind: "none" });
expect(descriptor.targetAgentSessionId).toBe("session-replay");
});
it("does not reuse dock nodes for empty launches into new windows", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
payload: {
openInNewWindow: true,
provider: "codex"
},
typeId: "agent-gui"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
openInNewWindow: true,
provider: "codex",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
});
it("treats dock popup new-window launches as new windows", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
launchSource: "dock-popup-new-window",
payload: {
provider: "codex"
},
typeId: "agent-gui"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
openInNewWindow: true,
provider: "codex",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
});
it("creates draft prompt launch requests for the unified dock entry", () => {
expect(
createAgentGuiWorkbenchDraftLaunchRequest({
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
provider: "codex",
userProjectPath: "/Users/example/project"
})
).toEqual({
dockEntryId: "agent-gui:unified",
payload: {
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
provider: "codex",
userProjectPath: "/Users/example/project"
},
reason: "host",
typeId: "agent-gui"
});
});
it("launches draft prompts without reusing an unrelated unified node", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor(
createAgentGuiWorkbenchDraftLaunchRequest({
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
provider: "codex"
})
)
).toMatchObject({
activation: {
payload: {
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
provider: "codex"
},
type: agentGuiWorkbenchPrefillPromptActivationType
},
dockEntryId: "agent-gui:unified",
provider: "codex",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
});
it("launches draft prompts into new windows when requested", () => {
const descriptor = createAgentGuiWorkbenchLaunchDescriptor(
createAgentGuiWorkbenchDraftLaunchRequest({
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
openInNewWindow: true,
provider: "codex"
})
);
expect(descriptor).toMatchObject({
activation: {
payload: {
agentTargetId: "local:codex",
draftPrompt: "Review this issue",
provider: "codex"
},
type: agentGuiWorkbenchPrefillPromptActivationType
},
dockEntryId: "agent-gui:unified",
openInNewWindow: true,
provider: "codex",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
expect(descriptor.instanceId).toMatch(/^agent-gui:instance:/);
});
it("creates session launch requests for the unified dock entry", () => {
expect(
createAgentGuiWorkbenchSessionLaunchRequest({
agentSessionId: "session-2",
provider: "claude-code"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
payload: {
agentSessionId: "session-2",
provider: "claude-code"
}
});
});
it("does not reuse a shared unified aggregate dock node for provider-specific draft prompts", () => {
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
payload: {
draftPrompt: "Review this issue",
provider: "codex"
},
typeId: "agent-gui"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
provider: "codex",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
expect(
createAgentGuiWorkbenchLaunchDescriptor({
dockEntryId: agentGuiWorkbenchUnifiedDockEntryId(),
payload: {
draftPrompt: "Review this issue",
provider: "claude-code"
},
typeId: "agent-gui"
})
).toMatchObject({
dockEntryId: "agent-gui:unified",
provider: "claude-code",
reusePolicy: { kind: "none" },
targetAgentSessionId: null
});
});
});