2026-03-17 17:25:46 +09:00
|
|
|
import { describe, expect, test } from "bun:test"
|
|
|
|
|
|
2026-03-27 12:05:00 +08:00
|
|
|
import { extractSessionIdFromMetadata, extractSessionIdFromOutput } from "./subagent-session-id"
|
2026-03-17 17:25:46 +09:00
|
|
|
|
|
|
|
|
describe("extractSessionIdFromOutput", () => {
|
|
|
|
|
test("extracts Session ID blocks from background output", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = `Background task launched.\n\nSession ID: ses_bg_12345`
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_bg_12345")
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("extracts session_id from task metadata blocks", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = `Task completed.\n\n<task_metadata>\nsession_id: ses_sync_12345\n</task_metadata>`
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_sync_12345")
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-18 18:44:42 +09:00
|
|
|
test("extracts hyphenated session IDs from task metadata blocks", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = `Task completed.\n\n<task_metadata>\nsession_id: ses_auth-flow-123\n</task_metadata>`
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_auth-flow-123")
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-17 17:25:46 +09:00
|
|
|
test("returns undefined when no session id is present", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = "Task completed without metadata"
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("prefers the session id inside the trailing task_metadata block", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = `The previous attempt mentioned session_id: ses_wrong_body_123 but that was only context.
|
|
|
|
|
|
|
|
|
|
<task_metadata>
|
|
|
|
|
session_id: ses_real_metadata_456
|
|
|
|
|
</task_metadata>`
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_real_metadata_456")
|
|
|
|
|
})
|
2026-03-17 18:14:17 +09:00
|
|
|
|
|
|
|
|
test("does not let task_metadata parsing bleed into incidental body text after the closing tag", () => {
|
|
|
|
|
// given
|
|
|
|
|
const output = `<task_metadata>
|
|
|
|
|
session_id: ses_real_metadata_456
|
|
|
|
|
</task_metadata>
|
|
|
|
|
|
|
|
|
|
debug log: session_id: ses_wrong_body_789`
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromOutput(output)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_real_metadata_456")
|
|
|
|
|
})
|
2026-03-17 17:25:46 +09:00
|
|
|
})
|
2026-03-27 12:05:00 +08:00
|
|
|
|
|
|
|
|
describe("extractSessionIdFromMetadata", () => {
|
|
|
|
|
test("extracts sessionId from tool metadata object", () => {
|
|
|
|
|
// given
|
|
|
|
|
const metadata = { sessionId: "ses_plugin_abc123" }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromMetadata(metadata)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_plugin_abc123")
|
|
|
|
|
})
|
|
|
|
|
|
2026-04-16 13:52:12 +09:00
|
|
|
test("extracts legacy session aliases from tool metadata object", () => {
|
|
|
|
|
// given
|
|
|
|
|
const metadata = { sessionID: "ses_plugin_alias_123" }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromMetadata(metadata)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBe("ses_plugin_alias_123")
|
|
|
|
|
})
|
|
|
|
|
|
2026-03-27 12:05:00 +08:00
|
|
|
test("returns undefined for metadata without sessionId", () => {
|
|
|
|
|
// given
|
|
|
|
|
const metadata = { title: "some task" }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromMetadata(metadata)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("returns undefined for non-object metadata", () => {
|
|
|
|
|
expect(extractSessionIdFromMetadata(null)).toBeUndefined()
|
|
|
|
|
expect(extractSessionIdFromMetadata(undefined)).toBeUndefined()
|
|
|
|
|
expect(extractSessionIdFromMetadata("string")).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test("rejects sessionId values that don't start with ses_", () => {
|
|
|
|
|
// given
|
|
|
|
|
const metadata = { sessionId: "not-a-session-id" }
|
|
|
|
|
|
|
|
|
|
// when
|
|
|
|
|
const result = extractSessionIdFromMetadata(metadata)
|
|
|
|
|
|
|
|
|
|
// then
|
|
|
|
|
expect(result).toBeUndefined()
|
|
|
|
|
})
|
|
|
|
|
})
|