Files
oh-my-openagent/src/features/background-agent/compaction-aware-message-resolver.test.ts
YeonGyu-Kim d1e5bd63c1 fix: address Oracle + Cubic review feedback for background-agent refactoring
- Revert getMessageDir to original join(MESSAGE_STORAGE, sessionID) behavior
- Fix dead subagentSessions.delete by capturing previousSessionID before tryFallbackRetry
- Add .unref() to process cleanup setTimeout to prevent 6s hang on Ctrl-C
- Add missing isUnstableAgent to fallback retry input mapping
- Fix process-cleanup tests to use exit listener instead of SIGINT at index 0
- Swap test filenames in compaction-aware-message-resolver to exercise skip logic correctly
2026-02-22 12:14:26 +09:00

191 lines
5.4 KiB
TypeScript

import { describe, test, expect, beforeEach, afterEach } from "bun:test"
import { mkdtempSync, writeFileSync, rmSync } from "node:fs"
import { join } from "node:path"
import { tmpdir } from "node:os"
import { isCompactionAgent, findNearestMessageExcludingCompaction } from "./compaction-aware-message-resolver"
describe("isCompactionAgent", () => {
describe("#given agent name variations", () => {
test("returns true for 'compaction'", () => {
// when
const result = isCompactionAgent("compaction")
// then
expect(result).toBe(true)
})
test("returns true for 'Compaction' (case insensitive)", () => {
// when
const result = isCompactionAgent("Compaction")
// then
expect(result).toBe(true)
})
test("returns true for ' compaction ' (with whitespace)", () => {
// when
const result = isCompactionAgent(" compaction ")
// then
expect(result).toBe(true)
})
test("returns false for undefined", () => {
// when
const result = isCompactionAgent(undefined)
// then
expect(result).toBe(false)
})
test("returns false for null", () => {
// when
const result = isCompactionAgent(null as unknown as string)
// then
expect(result).toBe(false)
})
test("returns false for non-compaction agent like 'sisyphus'", () => {
// when
const result = isCompactionAgent("sisyphus")
// then
expect(result).toBe(false)
})
})
})
describe("findNearestMessageExcludingCompaction", () => {
let tempDir: string
beforeEach(() => {
tempDir = mkdtempSync(join(tmpdir(), "compaction-test-"))
})
afterEach(() => {
rmSync(tempDir, { force: true, recursive: true })
})
describe("#given directory with messages", () => {
test("finds message with full agent and model", () => {
// given
const message = {
agent: "sisyphus",
model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
}
writeFileSync(join(tempDir, "001.json"), JSON.stringify(message))
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).not.toBeNull()
expect(result?.agent).toBe("sisyphus")
expect(result?.model?.providerID).toBe("anthropic")
expect(result?.model?.modelID).toBe("claude-opus-4-6")
})
test("skips compaction agent messages", () => {
// given
const compactionMessage = {
agent: "compaction",
model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
}
const validMessage = {
agent: "sisyphus",
model: { providerID: "anthropic", modelID: "claude-opus-4-6" },
}
writeFileSync(join(tempDir, "002.json"), JSON.stringify(compactionMessage))
writeFileSync(join(tempDir, "001.json"), JSON.stringify(validMessage))
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).not.toBeNull()
expect(result?.agent).toBe("sisyphus")
})
test("falls back to partial agent/model match", () => {
// given
const messageWithAgentOnly = {
agent: "hephaestus",
}
const messageWithModelOnly = {
model: { providerID: "openai", modelID: "gpt-5.3" },
}
writeFileSync(join(tempDir, "001.json"), JSON.stringify(messageWithModelOnly))
writeFileSync(join(tempDir, "002.json"), JSON.stringify(messageWithAgentOnly))
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).not.toBeNull()
// Should find the one with agent first (sorted reverse, so 002 is checked first)
expect(result?.agent).toBe("hephaestus")
})
test("returns null for empty directory", () => {
// given - empty directory (tempDir is already empty)
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).toBeNull()
})
test("returns null for non-existent directory", () => {
// given
const nonExistentDir = join(tmpdir(), "non-existent-dir-12345")
// when
const result = findNearestMessageExcludingCompaction(nonExistentDir)
// then
expect(result).toBeNull()
})
test("skips invalid JSON files and finds valid message", () => {
// given
const invalidJson = "{ invalid json"
const validMessage = {
agent: "oracle",
model: { providerID: "google", modelID: "gemini-2-flash" },
}
writeFileSync(join(tempDir, "002.json"), invalidJson)
writeFileSync(join(tempDir, "001.json"), JSON.stringify(validMessage))
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).not.toBeNull()
expect(result?.agent).toBe("oracle")
})
test("finds newest valid message (sorted by filename reverse)", () => {
// given
const olderMessage = {
agent: "older",
model: { providerID: "a", modelID: "b" },
}
const newerMessage = {
agent: "newer",
model: { providerID: "c", modelID: "d" },
}
writeFileSync(join(tempDir, "001.json"), JSON.stringify(olderMessage))
writeFileSync(join(tempDir, "010.json"), JSON.stringify(newerMessage))
// when
const result = findNearestMessageExcludingCompaction(tempDir)
// then
expect(result).not.toBeNull()
expect(result?.agent).toBe("newer")
})
})
})