fix(hook-message-injector): use monotonic counter for deterministic message/part IDs
This commit is contained in:
parent
cc6ab1addc
commit
6e9f27350d
@ -4,6 +4,8 @@ import {
|
|||||||
findFirstMessageWithAgent,
|
findFirstMessageWithAgent,
|
||||||
findNearestMessageWithFieldsFromSDK,
|
findNearestMessageWithFieldsFromSDK,
|
||||||
findFirstMessageWithAgentFromSDK,
|
findFirstMessageWithAgentFromSDK,
|
||||||
|
generateMessageId,
|
||||||
|
generatePartId,
|
||||||
injectHookMessage,
|
injectHookMessage,
|
||||||
} from "./injector"
|
} from "./injector"
|
||||||
import { isSqliteBackend, resetSqliteBackendCache } from "../../shared/opencode-storage-detection"
|
import { isSqliteBackend, resetSqliteBackendCache } from "../../shared/opencode-storage-detection"
|
||||||
@ -192,6 +194,38 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("generateMessageId", () => {
|
||||||
|
it("returns deterministic sequential IDs with fixed format", () => {
|
||||||
|
// given
|
||||||
|
const format = /^msg_\d{12}$/
|
||||||
|
|
||||||
|
// when
|
||||||
|
const firstId = generateMessageId()
|
||||||
|
const secondId = generateMessageId()
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(firstId).toMatch(format)
|
||||||
|
expect(secondId).toMatch(format)
|
||||||
|
expect(Number(secondId.slice(4))).toBe(Number(firstId.slice(4)) + 1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("generatePartId", () => {
|
||||||
|
it("returns deterministic sequential IDs with fixed format", () => {
|
||||||
|
// given
|
||||||
|
const format = /^prt_\d{12}$/
|
||||||
|
|
||||||
|
// when
|
||||||
|
const firstId = generatePartId()
|
||||||
|
const secondId = generatePartId()
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(firstId).toMatch(format)
|
||||||
|
expect(secondId).toMatch(format)
|
||||||
|
expect(Number(secondId.slice(4))).toBe(Number(firstId.slice(4)) + 1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("injectHookMessage", () => {
|
describe("injectHookMessage", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks()
|
vi.clearAllMocks()
|
||||||
|
|||||||
@ -29,6 +29,9 @@ interface SDKMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let messageCounter = 0
|
||||||
|
let partCounter = 0
|
||||||
|
|
||||||
function convertSDKMessageToStoredMessage(msg: SDKMessage): StoredMessage | null {
|
function convertSDKMessageToStoredMessage(msg: SDKMessage): StoredMessage | null {
|
||||||
const info = msg.info
|
const info = msg.info
|
||||||
if (!info) return null
|
if (!info) return null
|
||||||
@ -204,16 +207,12 @@ export function findFirstMessageWithAgent(messageDir: string): string | null {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateMessageId(): string {
|
export function generateMessageId(): string {
|
||||||
const timestamp = Date.now().toString(16)
|
return `msg_${String(++messageCounter).padStart(12, "0")}`
|
||||||
const random = Math.random().toString(36).substring(2, 14)
|
|
||||||
return `msg_${timestamp}${random}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePartId(): string {
|
export function generatePartId(): string {
|
||||||
const timestamp = Date.now().toString(16)
|
return `prt_${String(++partCounter).padStart(12, "0")}`
|
||||||
const random = Math.random().toString(36).substring(2, 10)
|
|
||||||
return `prt_${timestamp}${random}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOrCreateMessageDir(sessionID: string): string {
|
function getOrCreateMessageDir(sessionID: string): string {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user