Merge pull request #2212 from code-yeongyu/fix/h5-collector-ordering
fix(context-injector): use monotonic registration order instead of timestamp for deterministic sorting
This commit is contained in:
@@ -205,6 +205,45 @@ describe("ContextCollector", () => {
|
||||
const ids = pending.entries.map((e) => e.id)
|
||||
expect(ids).toEqual(["first", "second", "third"])
|
||||
})
|
||||
|
||||
it("keeps registration order even when Date.now values are not monotonic", () => {
|
||||
// given
|
||||
const sessionID = "ses_order_non_monotonic_time"
|
||||
const originalDateNow = Date.now
|
||||
const mockedTimestamps = [300, 100, 200]
|
||||
let timestampIndex = 0
|
||||
Date.now = () => mockedTimestamps[timestampIndex++] ?? 0
|
||||
|
||||
try {
|
||||
collector.register(sessionID, {
|
||||
id: "first",
|
||||
source: "custom",
|
||||
content: "First",
|
||||
priority: "normal",
|
||||
})
|
||||
collector.register(sessionID, {
|
||||
id: "second",
|
||||
source: "custom",
|
||||
content: "Second",
|
||||
priority: "normal",
|
||||
})
|
||||
collector.register(sessionID, {
|
||||
id: "third",
|
||||
source: "custom",
|
||||
content: "Third",
|
||||
priority: "normal",
|
||||
})
|
||||
} finally {
|
||||
Date.now = originalDateNow
|
||||
}
|
||||
|
||||
// when
|
||||
const pending = collector.getPending(sessionID)
|
||||
|
||||
// then
|
||||
const ids = pending.entries.map((entry) => entry.id)
|
||||
expect(ids).toEqual(["first", "second", "third"])
|
||||
})
|
||||
})
|
||||
|
||||
describe("consume", () => {
|
||||
|
||||
@@ -14,6 +14,8 @@ const PRIORITY_ORDER: Record<ContextPriority, number> = {
|
||||
|
||||
const CONTEXT_SEPARATOR = "\n\n---\n\n"
|
||||
|
||||
let registrationCounter = 0
|
||||
|
||||
export class ContextCollector {
|
||||
private sessions: Map<string, Map<string, ContextEntry>> = new Map()
|
||||
|
||||
@@ -30,7 +32,7 @@ export class ContextCollector {
|
||||
source: options.source,
|
||||
content: options.content,
|
||||
priority: options.priority ?? "normal",
|
||||
timestamp: Date.now(),
|
||||
registrationOrder: ++registrationCounter,
|
||||
metadata: options.metadata,
|
||||
}
|
||||
|
||||
@@ -77,7 +79,7 @@ export class ContextCollector {
|
||||
return entries.sort((a, b) => {
|
||||
const priorityDiff = PRIORITY_ORDER[a.priority] - PRIORITY_ORDER[b.priority]
|
||||
if (priorityDiff !== 0) return priorityDiff
|
||||
return a.timestamp - b.timestamp
|
||||
return a.registrationOrder - b.registrationOrder
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ export interface ContextEntry {
|
||||
content: string
|
||||
/** Priority for ordering (default: normal) */
|
||||
priority: ContextPriority
|
||||
/** Timestamp when registered */
|
||||
timestamp: number
|
||||
/** Monotonic order when registered */
|
||||
registrationOrder: number
|
||||
/** Optional metadata for debugging/logging */
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user