79 lines
2.4 KiB
TypeScript
79 lines
2.4 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
|
|
import { getSessionInfoForTask } from "./session-info";
|
|
import type { TaskSession } from "@/lib/types/http";
|
|
|
|
function session(overrides: Partial<TaskSession>): TaskSession {
|
|
return {
|
|
id: overrides.id ?? "s1",
|
|
task_id: overrides.task_id ?? "t1",
|
|
state: overrides.state ?? "WAITING_FOR_INPUT",
|
|
started_at: overrides.started_at ?? "",
|
|
updated_at: overrides.updated_at ?? "",
|
|
is_primary: overrides.is_primary ?? false,
|
|
...overrides,
|
|
} as TaskSession;
|
|
}
|
|
|
|
describe("getSessionInfoForTask", () => {
|
|
it("returns undefined sessionState when the task has no sessions", () => {
|
|
const info = getSessionInfoForTask("t1", {}, {});
|
|
expect(info.sessionState).toBeUndefined();
|
|
});
|
|
|
|
it("returns the primary session's state when it is the only session", () => {
|
|
const info = getSessionInfoForTask(
|
|
"t1",
|
|
{ t1: [session({ id: "p", is_primary: true, state: "WAITING_FOR_INPUT" })] },
|
|
{},
|
|
);
|
|
expect(info.sessionState).toBe("WAITING_FOR_INPUT");
|
|
});
|
|
|
|
// Regression: the sidebar derives its "running" badge from this state.
|
|
// A secondary chat tab that the user opens while the primary is idle must
|
|
// still surface as "in progress" — without this the task keeps showing
|
|
// "Turn Finished" while the new agent is working.
|
|
it("returns RUNNING when any non-primary session is running, even if primary is idle", () => {
|
|
const info = getSessionInfoForTask(
|
|
"t1",
|
|
{
|
|
t1: [
|
|
session({ id: "p", is_primary: true, state: "WAITING_FOR_INPUT" }),
|
|
session({ id: "s", state: "RUNNING" }),
|
|
],
|
|
},
|
|
{},
|
|
);
|
|
expect(info.sessionState).toBe("RUNNING");
|
|
});
|
|
|
|
it("prefers RUNNING over STARTING", () => {
|
|
const info = getSessionInfoForTask(
|
|
"t1",
|
|
{
|
|
t1: [
|
|
session({ id: "p", is_primary: true, state: "STARTING" }),
|
|
session({ id: "s", state: "RUNNING" }),
|
|
],
|
|
},
|
|
{},
|
|
);
|
|
expect(info.sessionState).toBe("RUNNING");
|
|
});
|
|
|
|
it("falls back to the primary's state when no session is more active", () => {
|
|
const info = getSessionInfoForTask(
|
|
"t1",
|
|
{
|
|
t1: [
|
|
session({ id: "p", is_primary: true, state: "WAITING_FOR_INPUT" }),
|
|
session({ id: "s", state: "COMPLETED" }),
|
|
],
|
|
},
|
|
{},
|
|
);
|
|
expect(info.sessionState).toBe("WAITING_FOR_INPUT");
|
|
});
|
|
});
|