76 lines
2.8 KiB
TypeScript
76 lines
2.8 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { findPrimaryProjectAgentSession } from '@/lib/project-agent-session';
|
|
|
|
describe('project Agent primary session selection', () => {
|
|
it('prefers an older active session over a newer empty duplicate', () => {
|
|
const empty = {
|
|
id: 'ses_empty',
|
|
agent: 'game-design',
|
|
time: { created: 200, updated: 200 },
|
|
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
cost: 0,
|
|
};
|
|
const historical = {
|
|
id: 'ses_history',
|
|
agent: 'game-design',
|
|
time: { created: 100, updated: 150 },
|
|
tokens: { input: 10, output: 20, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
cost: 0.1,
|
|
};
|
|
|
|
expect(findPrimaryProjectAgentSession([empty, historical], 'game-design')).toBe(historical);
|
|
});
|
|
|
|
it('keeps runtime order when multiple matching sessions are active', () => {
|
|
const newest = { id: 'ses_newest', agent: 'game-design', time: { created: 100, updated: 300 } };
|
|
const older = { id: 'ses_older', agent: 'game-design', time: { created: 100, updated: 200 } };
|
|
|
|
expect(findPrimaryProjectAgentSession([newest, older], 'game-design')).toBe(newest);
|
|
});
|
|
|
|
it('reuses the first empty match instead of requesting another duplicate', () => {
|
|
const first = { id: 'ses_first', agent: 'game-art', time: { created: 200, updated: 200 } };
|
|
const second = { id: 'ses_second', agent: 'game-art', time: { created: 100, updated: 100 } };
|
|
|
|
expect(findPrimaryProjectAgentSession([first, second], 'game-art')).toBe(first);
|
|
});
|
|
|
|
it('ignores sessions owned by other Agents', () => {
|
|
expect(findPrimaryProjectAgentSession([
|
|
{ id: 'ses_other', agent: 'game-development', time: { created: 100, updated: 200 } },
|
|
], 'game-design')).toBeUndefined();
|
|
});
|
|
|
|
it('recognizes legacy string timestamps and token activity', () => {
|
|
const legacy = {
|
|
id: 'ses_legacy',
|
|
agent: 'game-design',
|
|
createdAt: '2026-07-13T00:00:00.000Z',
|
|
updatedAt: '2026-07-13T00:01:00.000Z',
|
|
};
|
|
const tokenOnly = {
|
|
id: 'ses_token',
|
|
agent: 'game-art',
|
|
tokens: { input: 1, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
|
};
|
|
|
|
expect(findPrimaryProjectAgentSession([legacy], 'game-design')).toBe(legacy);
|
|
expect(findPrimaryProjectAgentSession([tokenOnly], 'game-art')).toBe(tokenOnly);
|
|
});
|
|
|
|
it('does not treat an all-zero summary as conversation activity', () => {
|
|
const emptySummary = {
|
|
id: 'ses_empty_summary',
|
|
agent: 'game-design',
|
|
summary: { additions: 0, deletions: 0, files: 0, diffs: [] },
|
|
};
|
|
const historical = {
|
|
id: 'ses_historical_summary',
|
|
agent: 'game-design',
|
|
summary: { additions: 1, deletions: 0, files: 1, diffs: [] },
|
|
};
|
|
|
|
expect(findPrimaryProjectAgentSession([emptySummary, historical], 'game-design')).toBe(historical);
|
|
});
|
|
});
|