Transcript Incremental Projection
Nucleic-Session: 0FFD007B-0696-4517-9429-129C7B0FD5AC Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
@@ -123,17 +123,37 @@ struct SessionDetailView: View {
|
||||
set: { store.setSessionEffort(sessionID, $0) })
|
||||
}
|
||||
|
||||
/// Memo for the context-occupancy scan below. The backward scan usually stops at the last
|
||||
/// turn's usage event, but a stream with sparse (or no) usage reporting walks the whole
|
||||
/// transcript — and `body` re-evaluates on every store change and keystroke, so an O(N) scan
|
||||
/// per evaluation quietly compounds on long sessions. `(count, lastSeq)` pins the stream, as
|
||||
/// in the projection cache; a class held in `@State` so updating it from `body` doesn't
|
||||
/// itself invalidate the view.
|
||||
private final class ContextScanCache {
|
||||
var count = -1
|
||||
var lastSeq: UInt64 = 0
|
||||
var used: Int?
|
||||
}
|
||||
@State private var contextScanCache = ContextScanCache()
|
||||
|
||||
/// Live context-window occupancy (newest turn's input tokens ÷ the model's window), read
|
||||
/// from the transcript exactly as the Mac header does.
|
||||
/// from the transcript exactly as the Mac header does. Only the token scan is memoized —
|
||||
/// the window division stays live, so a model switch reflects immediately.
|
||||
private var contextPercent: Int? {
|
||||
let used = store.openEvents.reversed().lazy.compactMap { event -> Int? in
|
||||
switch event.kind {
|
||||
case .turnCompleted(let turn): return turn.usage?.contextInputTokens
|
||||
case .usage(let usage): return usage.contextInputTokens
|
||||
default: return nil
|
||||
}
|
||||
}.first { $0 > 0 }
|
||||
guard let used else { return nil }
|
||||
let events = store.openEvents
|
||||
let cache = contextScanCache
|
||||
if cache.count != events.count || cache.lastSeq != events.last?.seq ?? 0 {
|
||||
cache.count = events.count
|
||||
cache.lastSeq = events.last?.seq ?? 0
|
||||
cache.used = events.reversed().lazy.compactMap { event -> Int? in
|
||||
switch event.kind {
|
||||
case .turnCompleted(let turn): return turn.usage?.contextInputTokens
|
||||
case .usage(let usage): return usage.contextInputTokens
|
||||
default: return nil
|
||||
}
|
||||
}.first { $0 > 0 }
|
||||
}
|
||||
guard let used = cache.used else { return nil }
|
||||
let window = store.modelCatalog.contextWindow(summary?.model)
|
||||
guard window > 0 else { return nil }
|
||||
return min(100, Int((Double(used) / Double(window)) * 100))
|
||||
|
||||
Reference in New Issue
Block a user