session-cache.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import type {
  2. Message,
  3. Part,
  4. PermissionRequest,
  5. QuestionRequest,
  6. SessionStatus,
  7. SnapshotFileDiff,
  8. Todo,
  9. } from "@opencode-ai/sdk/v2/client"
  10. export const SESSION_CACHE_LIMIT = 40
  11. type SessionCache = {
  12. session_status: Record<string, SessionStatus | undefined>
  13. session_diff: Record<string, SnapshotFileDiff[] | undefined>
  14. todo: Record<string, Todo[] | undefined>
  15. message: Record<string, Message[] | undefined>
  16. part: Record<string, Part[] | undefined>
  17. permission: Record<string, PermissionRequest[] | undefined>
  18. question: Record<string, QuestionRequest[] | undefined>
  19. part_text_accum_delta: Record<string, string | undefined>
  20. }
  21. export function dropSessionCaches(store: SessionCache, sessionIDs: Iterable<string>) {
  22. const stale = new Set(Array.from(sessionIDs).filter(Boolean))
  23. if (stale.size === 0) return
  24. for (const key of Object.keys(store.part)) {
  25. const parts = store.part[key]
  26. if (!parts?.some((part) => stale.has(part?.sessionID ?? ""))) continue
  27. for (const part of parts) {
  28. delete store.part_text_accum_delta[part.id]
  29. }
  30. delete store.part[key]
  31. }
  32. for (const sessionID of stale) {
  33. delete store.message[sessionID]
  34. delete store.todo[sessionID]
  35. delete store.session_diff[sessionID]
  36. delete store.session_status[sessionID]
  37. delete store.permission[sessionID]
  38. delete store.question[sessionID]
  39. }
  40. }
  41. export function pickSessionCacheEvictions(input: {
  42. seen: Set<string>
  43. keep: string
  44. limit: number
  45. preserve?: Iterable<string>
  46. }) {
  47. const stale: string[] = []
  48. const keep = new Set([input.keep, ...Array.from(input.preserve ?? [])])
  49. if (input.seen.has(input.keep)) input.seen.delete(input.keep)
  50. input.seen.add(input.keep)
  51. for (const id of input.seen) {
  52. if (input.seen.size - stale.length <= input.limit) break
  53. if (keep.has(id)) continue
  54. stale.push(id)
  55. }
  56. for (const id of stale) {
  57. input.seen.delete(id)
  58. }
  59. return stale
  60. }