feat(atlas): enhance session-last-agent with timestamp-based ordering

- Sort messages by creation timestamp for accurate last agent detection
- Add fallback to filename sorting for deterministic ordering
- Add JSON backend test coverage
- Update SQLite backend tests for timestamp-aware sorting

🤖 Generated with assistance of OhMyOpenCode
This commit is contained in:
YeonGyu-Kim
2026-04-05 17:14:34 +09:00
parent ec49bd553f
commit 9199dd545f
3 changed files with 159 additions and 56 deletions
@@ -1,56 +1,71 @@
export {}
const { describe, expect, mock, test, afterAll } = require("bun:test")
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => true,
}))
afterAll(() => { mock.restore() })
async function importFreshSessionLastAgentModule() {
mock.module("../../shared/opencode-message-dir", () => ({
getMessageDir: () => null,
}))
const { getLastAgentFromSession } = await import("./session-last-agent")
mock.module("../../shared/opencode-storage-detection", () => ({
isSqliteBackend: () => true,
}))
const module = await import(`./session-last-agent?test=${Date.now()}-${Math.random()}`)
mock.restore()
return module
}
const { getLastAgentFromSession } = await importFreshSessionLastAgentModule()
function createMockClient(messages: Array<{ info?: { agent?: string } }>) {
return {
session: {
messages: async () => ({ data: messages }),
},
}
}
describe("getLastAgentFromSession sqlite branch", () => {
test("should skip compaction and return the previous real agent from sqlite messages", async () => {
describe("getLastAgentFromSession SQLite backend ordering", () => {
test("returns newest non-compaction agent using time.created and id tie-breaker", async () => {
// given
const client = createMockClient([
{ info: { agent: "atlas" } },
{ info: { agent: "compaction" } },
])
const client = {
session: {
messages: async () => ({
data: [
{ id: "msg_0001", info: { agent: "atlas", time: { created: 100 } } },
{ id: "msg_0003", info: { agent: "compaction", time: { created: 200 } } },
{ id: "msg_0002", info: { agent: "sisyphus-junior", time: { created: 100 } } },
],
}),
},
}
// when
const result = await getLastAgentFromSession("ses_sqlite_compaction", client)
const result = await getLastAgentFromSession("ses_sqlite_last_agent", client as never)
// then
expect(result).toBe("atlas")
expect(result).toBe("sisyphus-junior")
})
test("should return null when sqlite history contains only compaction", async () => {
test("handles equal timestamps with random-looking ids deterministically", async () => {
// given
const client = createMockClient([{ info: { agent: "compaction" } }])
const client = {
session: {
messages: async () => ({
data: [
{ id: "msg_a91f00ab", info: { agent: "atlas", time: { created: 100 } } },
{ id: "msg_f0e1d2c3", info: { agent: "compaction", time: { created: 200 } } },
{ id: "msg_d4c3b2a1", info: { agent: "sisyphus-junior", time: { created: 100 } } },
],
}),
},
}
// when
const result = await getLastAgentFromSession("ses_sqlite_only_compaction", client)
const result = await getLastAgentFromSession("ses_sqlite_last_agent_equal_time", client as never)
// then
expect(result).toBe("sisyphus-junior")
})
test("returns null instead of throwing when SQLite message lookup fails", async () => {
// given
const client = {
session: {
messages: async () => {
throw new Error("sqlite lookup failed")
},
},
}
// when
const result = await getLastAgentFromSession("ses_sqlite_error", client as never)
// then
expect(result).toBeNull()
})
})
export {}