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
290 lines
7.8 KiB
TypeScript
290 lines
7.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
resolveInitialRailPlacement,
|
|
resolveInitialTuttiModeActivation,
|
|
resolveNewConversationSettingProvenance,
|
|
resolveSparseNewConversationActivationSettings
|
|
} from "./useAgentGUINewConversationActivation";
|
|
|
|
describe("resolveNewConversationSettingProvenance", () => {
|
|
it("marks presented draft values inherited and required values explicit", () => {
|
|
expect(resolveNewConversationSettingProvenance()).toEqual({
|
|
modelExplicit: false,
|
|
reasoningEffortExplicit: false
|
|
});
|
|
expect(
|
|
resolveNewConversationSettingProvenance({
|
|
model: "gpt-selected",
|
|
reasoningEffort: "high"
|
|
})
|
|
).toEqual({ modelExplicit: true, reasoningEffortExplicit: true });
|
|
});
|
|
});
|
|
|
|
describe("resolveInitialRailPlacement", () => {
|
|
it("uses the selected caller project section", () => {
|
|
expect(
|
|
resolveInitialRailPlacement({
|
|
selectedProjectPath: "/workspace",
|
|
userProjects: [
|
|
{
|
|
id: "project-1",
|
|
label: "Workspace",
|
|
path: "/workspace",
|
|
pinnedAtUnixMs: 0,
|
|
sectionKey: "project:/workspace"
|
|
}
|
|
]
|
|
})
|
|
).toEqual({
|
|
version: 1,
|
|
kind: "project",
|
|
projectPath: "/workspace",
|
|
sectionKey: "project:/workspace"
|
|
});
|
|
});
|
|
|
|
it("uses conversations only when no project is selected", () => {
|
|
expect(
|
|
resolveInitialRailPlacement({
|
|
selectedProjectPath: null,
|
|
userProjects: []
|
|
})
|
|
).toEqual({
|
|
version: 1,
|
|
kind: "conversations",
|
|
sectionKey: "conversations"
|
|
});
|
|
});
|
|
|
|
it("writes the canonical project root when the selected path is nested", () => {
|
|
expect(
|
|
resolveInitialRailPlacement({
|
|
selectedProjectPath: "/workspace/packages/agent",
|
|
userProjects: [
|
|
{
|
|
id: "project-1",
|
|
label: "Workspace",
|
|
path: "/workspace",
|
|
pinnedAtUnixMs: 0,
|
|
sectionKey: "project:/workspace"
|
|
}
|
|
]
|
|
})
|
|
).toEqual({
|
|
version: 1,
|
|
kind: "project",
|
|
projectPath: "/workspace",
|
|
sectionKey: "project:/workspace"
|
|
});
|
|
});
|
|
|
|
it("fails closed when the selected project has no canonical section", () => {
|
|
expect(
|
|
resolveInitialRailPlacement({
|
|
selectedProjectPath: "/workspace",
|
|
userProjects: []
|
|
})
|
|
).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("resolveInitialTuttiModeActivation", () => {
|
|
it("prefers the composer submit snapshot over a stale inactive draft", () => {
|
|
expect(
|
|
resolveInitialTuttiModeActivation({
|
|
submitOptions: {
|
|
tuttiMode: { active: true, effect: 81, speed: 72 }
|
|
},
|
|
draftActive: false,
|
|
draftEffect: 50,
|
|
draftSpeed: 50
|
|
})
|
|
).toEqual({
|
|
activation: {
|
|
source: "slash_command",
|
|
status: "active",
|
|
effect: 81,
|
|
speed: 72
|
|
},
|
|
source: "composer_submit"
|
|
});
|
|
});
|
|
|
|
it("treats an explicit inactive submit snapshot as authoritative", () => {
|
|
expect(
|
|
resolveInitialTuttiModeActivation({
|
|
submitOptions: { tuttiMode: { active: false } },
|
|
draftActive: true,
|
|
draftEffect: 50,
|
|
draftSpeed: 50
|
|
})
|
|
).toBeNull();
|
|
});
|
|
|
|
it("keeps the engine draft fallback for non-composer callers", () => {
|
|
expect(
|
|
resolveInitialTuttiModeActivation({
|
|
draftActive: true,
|
|
draftEffect: 64,
|
|
draftSpeed: 75
|
|
})
|
|
).toEqual({
|
|
activation: {
|
|
source: "slash_command",
|
|
status: "active",
|
|
effect: 64,
|
|
speed: 75
|
|
},
|
|
source: "engine_draft"
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("resolveSparseNewConversationActivationSettings", () => {
|
|
it("keeps presented full-access after the optimistic draft was retired", () => {
|
|
expect(
|
|
resolveSparseNewConversationActivationSettings({
|
|
draftSettings: { model: "gpt-5.4" },
|
|
composerOptions: {
|
|
effectiveSettings: {
|
|
model: "gpt-5.4",
|
|
permissionModeId: "full-access"
|
|
},
|
|
permissionConfig: {
|
|
configurable: true,
|
|
defaultValue: "full-access",
|
|
modes: [
|
|
{ id: "auto", label: "Approve for me", semantic: "auto" },
|
|
{
|
|
id: "full-access",
|
|
label: "Full access",
|
|
semantic: "full-access"
|
|
}
|
|
]
|
|
},
|
|
models: [],
|
|
reasoningEfforts: [],
|
|
speeds: [],
|
|
capabilities: {},
|
|
behavior: {},
|
|
skills: [],
|
|
loadedAtUnixMs: 1
|
|
} as never
|
|
}).permissionModeId
|
|
).toBe("full-access");
|
|
});
|
|
|
|
it("prefers an explicit draft permission over remembered presentation", () => {
|
|
expect(
|
|
resolveSparseNewConversationActivationSettings({
|
|
draftSettings: { permissionModeId: "auto" },
|
|
composerOptions: {
|
|
effectiveSettings: { permissionModeId: "full-access" },
|
|
permissionConfig: {
|
|
configurable: true,
|
|
defaultValue: "full-access",
|
|
modes: [
|
|
{ id: "auto", label: "Approve for me", semantic: "auto" },
|
|
{
|
|
id: "full-access",
|
|
label: "Full access",
|
|
semantic: "full-access"
|
|
}
|
|
]
|
|
},
|
|
models: [],
|
|
reasoningEfforts: [],
|
|
speeds: [],
|
|
capabilities: {},
|
|
behavior: {},
|
|
skills: [],
|
|
loadedAtUnixMs: 1
|
|
} as never
|
|
}).permissionModeId
|
|
).toBe("auto");
|
|
});
|
|
|
|
it("clamps inherited OpenCode reasoning to the selected model catalog", () => {
|
|
expect(
|
|
resolveSparseNewConversationActivationSettings({
|
|
draftSettings: {
|
|
model: "openai/gpt-5.3-codex-spark",
|
|
reasoningEffort: "none"
|
|
},
|
|
composerOptions: {
|
|
provider: "opencode",
|
|
effectiveSettings: {},
|
|
reasoningOptionsByModel: {
|
|
"openai/gpt-5.3-codex-spark": {
|
|
defaultValue: "medium",
|
|
options: [
|
|
{ label: "Low", value: "low" },
|
|
{ label: "Medium", value: "medium" }
|
|
]
|
|
}
|
|
},
|
|
models: [],
|
|
reasoningEfforts: [],
|
|
speeds: [],
|
|
capabilities: {},
|
|
behavior: {},
|
|
skills: [],
|
|
loadedAtUnixMs: 1
|
|
} as never
|
|
}).reasoningEffort
|
|
).toBe("medium");
|
|
});
|
|
|
|
it("drops inherited OpenCode reasoning when model metadata is unavailable", () => {
|
|
expect(
|
|
resolveSparseNewConversationActivationSettings({
|
|
draftSettings: {
|
|
model: "openai/gpt-5.3-codex-spark",
|
|
reasoningEffort: "none"
|
|
},
|
|
composerOptions: {
|
|
provider: "opencode",
|
|
effectiveSettings: {},
|
|
models: [],
|
|
reasoningEfforts: [],
|
|
speeds: [],
|
|
capabilities: {},
|
|
behavior: {},
|
|
skills: [],
|
|
loadedAtUnixMs: 1
|
|
} as never
|
|
}).reasoningEffort
|
|
).toBeUndefined();
|
|
});
|
|
|
|
it("keeps an explicit required reasoning patch strict for Create", () => {
|
|
expect(
|
|
resolveSparseNewConversationActivationSettings({
|
|
draftSettings: {
|
|
model: "openai/gpt-5.3-codex-spark",
|
|
reasoningEffort: "medium"
|
|
},
|
|
requiredSettingsPatch: { reasoningEffort: "none" },
|
|
composerOptions: {
|
|
provider: "opencode",
|
|
effectiveSettings: {},
|
|
reasoningOptionsByModel: {
|
|
"openai/gpt-5.3-codex-spark": {
|
|
defaultValue: "medium",
|
|
options: [{ label: "Medium", value: "medium" }]
|
|
}
|
|
},
|
|
models: [],
|
|
reasoningEfforts: [],
|
|
speeds: [],
|
|
capabilities: {},
|
|
behavior: {},
|
|
skills: [],
|
|
loadedAtUnixMs: 1
|
|
} as never
|
|
}).reasoningEffort
|
|
).toBe("none");
|
|
});
|
|
});
|