Files
orca/src/shared/ai-vault-session-depth.ts
T
Neilandmmarabel c2c63e7f9a Avoid downloading unchanged paired-runtime session history (#27383)
* perf: avoid retransferring unchanged paired-runtime session history

Keep selected finite-depth history refreshes content-conditional while preserving scans, full old-peer replies, force refreshes and the existing cache lifetime.

Co-authored-by: mmarabel <166927047+mmarabel@users.noreply.github.com>

* perf(ai-vault): keep full host list behind unchanged replies for cache readers

---------

Co-authored-by: mmarabel <166927047+mmarabel@users.noreply.github.com>
2026-10-10 22:31:20 -07:00

66 lines
2.2 KiB
TypeScript

import {
createNormalizedPathInsideOrEqualMatcher,
normalizeRuntimePathForComparison
} from './cross-platform-path'
import type { AiVaultListArgs, AiVaultListResult } from './ai-vault-types'
export const DEFAULT_AI_VAULT_SCAN_LIMIT = 1000
export type AiVaultSessionDepth = number | 'unlimited'
export function requestedAiVaultSessionDepth(
args?: Pick<AiVaultListArgs, 'limit' | 'unlimited'>
): AiVaultSessionDepth {
if (args?.unlimited === true) {
return 'unlimited'
}
return args?.limit && Number.isFinite(args.limit) && args.limit > 0
? Math.floor(args.limit)
: DEFAULT_AI_VAULT_SCAN_LIMIT
}
// Scanners bound with slice/comparisons, so 'unlimited' resolves to no bound.
// Single owner of the normalization every scan limit goes through.
export function aiVaultScanLimit(args?: Pick<AiVaultListArgs, 'limit' | 'unlimited'>): number {
const depth = requestedAiVaultSessionDepth(args)
return depth === 'unlimited' ? Number.POSITIVE_INFINITY : depth
}
export function aiVaultSessionDepthCovers(
cached: AiVaultSessionDepth,
requested: AiVaultSessionDepth
): boolean {
return cached === 'unlimited' || (requested !== 'unlimited' && cached >= requested)
}
export function truncateAiVaultListResult(
result: AiVaultListResult,
depth: AiVaultSessionDepth,
scopePaths: readonly string[] = []
): AiVaultListResult {
if (depth === 'unlimited') {
return result
}
const selectedIds = new Set(result.sessions.slice(0, depth).map((session) => session.id))
if (scopePaths.length > 0) {
const scopeMatchers = scopePaths.map(createNormalizedPathInsideOrEqualMatcher)
let scopedCount = 0
for (const session of result.sessions) {
const cwd = session.cwd
const normalizedCwd = cwd ? normalizeRuntimePathForComparison(cwd) : null
if (normalizedCwd !== null && scopeMatchers.some((matches) => matches(normalizedCwd))) {
selectedIds.add(session.id)
if (++scopedCount >= depth) {
break
}
}
}
}
const sessions = result.sessions.filter((session) => selectedIds.has(session.id))
return {
...result,
sessions,
...(sessions.length !== result.sessions.length ? { fingerprint: undefined } : {})
}
}