Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Generated by Scripts/regenerate-codex-parser-hash.sh. Do not edit by hand.

enum CodexParserHash {
static let value = "338e4ab0fe153f95"
static let value = "48ac20dad61e9a7f"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,25 @@ extension CostUsageScanner {
}

/// Subagent source is lineage evidence, not counter semantics. The first session metadata
/// owns leaf identity; only embedded metadata proves that this rollout copied an ancestor
/// prefix. Do not restore a blanket "all subagents are independent/inherited" rule.
/// owns leaf identity. Embedded ancestor metadata proves a copied prefix by itself; compact
/// rollouts need both the first-turn boundary and an exact parent snapshot match in the scanner.
/// Do not restore a blanket "all subagents are independent/inherited" rule.
struct CodexSubagentRolloutShape {
let counterSemantics: CodexSubagentCounterSemantics
let ownedSuffix: CodexSubagentOwnedSuffix?
let ownedSuffixCandidate: CodexSubagentOwnedSuffixCandidate?
let inferredParentSessionID: String?

struct CodexSubagentOwnedSuffix {
let startLineIndex: Int
let rawTotalsBaseline: CostUsageCodexTotals
}

struct CodexSubagentOwnedSuffixCandidate {
let ownedSuffix: CodexSubagentOwnedSuffix
let parentTotalsAtBoundary: CostUsageCodexTotals
}

struct Observation {
let lineIndex: Int
let kind: Kind
Expand Down Expand Up @@ -50,12 +57,14 @@ extension CostUsageScanner {
return Self(
counterSemantics: hasEmbeddedAncestor ? .copiedPrefix : .independent,
ownedSuffix: nil,
ownedSuffixCandidate: nil,
inferredParentSessionID: inferredParentSessionID)
}

static func classify(
leafSessionID: String?,
observations: [Observation]) -> Self
observations: [Observation],
hasExplicitParent: Bool = false) -> Self
{
let metadataIDs = observations.reduce(into: [String?]()) { result, observation in
guard case let .sessionMetadata(id) = observation.kind else { return }
Expand All @@ -64,14 +73,19 @@ extension CostUsageScanner {
let metadataShape = Self.classify(
leafSessionID: leafSessionID,
observedSessionIDs: metadataIDs)
guard metadataShape.counterSemantics == .copiedPrefix else { return metadataShape }
let canProposeParentConfirmedSuffix = metadataShape.counterSemantics == .independent
&& hasExplicitParent
guard metadataShape.counterSemantics == .copiedPrefix || canProposeParentConfirmedSuffix
else { return metadataShape }

let normalizedLeafID = Self.normalizedSessionID(leafSessionID)
var lastRawTotals: CostUsageCodexTotals?
var pendingTurnContext: (lineIndex: Int, baseline: CostUsageCodexTotals)?
var ownedSuffix: CodexSubagentOwnedSuffix?
var parentTotalsAtBoundary: CostUsageCodexTotals?
var inspectedOwnedSuffixFirstTotal = false
var observedAuthoritativeMetadata = false
var observedTurnContext = false

for observation in observations {
switch observation.kind {
Expand All @@ -88,22 +102,32 @@ extension CostUsageScanner {
if isEmbeddedAncestor {
// A later ancestor meta proves that any earlier candidate boundary was replay.
ownedSuffix = nil
parentTotalsAtBoundary = nil
inspectedOwnedSuffixFirstTotal = false
}
pendingTurnContext = nil

case .turnContext:
pendingTurnContext = lastRawTotals.map { (observation.lineIndex, $0) }
let isFirstTurnContext = !observedTurnContext
observedTurnContext = true
let acceptsBoundary = metadataShape.counterSemantics == .copiedPrefix
|| (canProposeParentConfirmedSuffix && isFirstTurnContext)
pendingTurnContext = acceptsBoundary
? lastRawTotals.map { (observation.lineIndex, $0) }
: nil

case let .interAgentCommunication(triggerTurn):
if ownedSuffix == nil,
triggerTurn,
let pendingTurnContext,
observation.lineIndex == pendingTurnContext.lineIndex + 1
observation.lineIndex == pendingTurnContext.lineIndex + 1,
metadataShape.counterSemantics == .copiedPrefix
|| Self.totalsContainUsage(pendingTurnContext.baseline)
{
ownedSuffix = Self.CodexSubagentOwnedSuffix(
startLineIndex: pendingTurnContext.lineIndex,
rawTotalsBaseline: pendingTurnContext.baseline)
parentTotalsAtBoundary = pendingTurnContext.baseline
inspectedOwnedSuffixFirstTotal = false
}
pendingTurnContext = nil
Expand Down Expand Up @@ -132,9 +156,25 @@ extension CostUsageScanner {
}
}

if metadataShape.counterSemantics == .copiedPrefix {
return Self(
counterSemantics: .copiedPrefix,
ownedSuffix: ownedSuffix,
ownedSuffixCandidate: nil,
inferredParentSessionID: metadataShape.inferredParentSessionID)
}

let candidate: CodexSubagentOwnedSuffixCandidate? = if let ownedSuffix, let parentTotalsAtBoundary {
Self.CodexSubagentOwnedSuffixCandidate(
ownedSuffix: ownedSuffix,
parentTotalsAtBoundary: parentTotalsAtBoundary)
} else {
nil
}
return Self(
counterSemantics: .copiedPrefix,
ownedSuffix: ownedSuffix,
counterSemantics: .independent,
ownedSuffix: nil,
ownedSuffixCandidate: candidate,
inferredParentSessionID: metadataShape.inferredParentSessionID)
}

Expand All @@ -153,6 +193,10 @@ extension CostUsageScanner {
lhs.input >= rhs.input && lhs.cached >= rhs.cached && lhs.output >= rhs.output
}

private static func totalsContainUsage(_ totals: CostUsageCodexTotals) -> Bool {
totals.input > 0 || totals.cached > 0 || totals.output > 0
}

private static func normalizedSessionID(_ value: String?) -> String? {
guard let value else { return nil }
let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
Expand Down
38 changes: 30 additions & 8 deletions Sources/CodexBarCore/Vendored/CostUsage/CostUsageScanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2040,6 +2040,8 @@ enum CostUsageScanner {
var forkTimestamp: String?
var subagentCounterSemantics: CodexSubagentCounterSemantics?
var usesLocalSubagentBoundary = false
var candidateBoundaryDependsOnParentTotals = false
var parentConfirmedLocalBoundary = false
var suppressUnownedCopiedPrefix = false
var inheritedTotals: CostUsageCodexTotals?
var remainingInheritedTotals: CostUsageCodexTotals?
Expand Down Expand Up @@ -2603,15 +2605,34 @@ enum CostUsageScanner {
}
let shape = CodexSubagentRolloutShape.classify(
leafSessionID: sessionId,
observations: observations)
observations: observations,
hasExplicitParent: forkedFromId != nil)
subagentCounterSemantics = shape.counterSemantics
if forkedFromId == nil {
forkedFromId = shape.inferredParentSessionID
}
suppressUnownedCopiedPrefix = shape.counterSemantics == .copiedPrefix
&& shape.ownedSuffix == nil
var ownedSuffix = shape.ownedSuffix
if let candidate = shape.ownedSuffixCandidate,
let parentSessionID = forkedFromId
{
candidateBoundaryDependsOnParentTotals = true
if let inheritedTotalsResolver {
switch try inheritedTotalsResolver(parentSessionID, forkTimestamp ?? "") {
case let .resolved(parentTotals):
if Self.codexTotalsEqual(parentTotals, candidate.parentTotalsAtBoundary) {
subagentCounterSemantics = .copiedPrefix
ownedSuffix = candidate.ownedSuffix
parentConfirmedLocalBoundary = true
}
case .unresolved:
break
}
}
}
suppressUnownedCopiedPrefix = subagentCounterSemantics == .copiedPrefix
&& ownedSuffix == nil
&& forkedFromId == nil
if let ownedSuffix = shape.ownedSuffix {
if let ownedSuffix {
usesLocalSubagentBoundary = true
previousTotals = nil
// Keep totals-derived accounting after the boundary. Real flat-total rows
Expand All @@ -2632,7 +2653,8 @@ enum CostUsageScanner {
metadata: [
"sessionId": sessionId ?? "unknown",
"semantics": subagentCounterSemantics == .copiedPrefix ? "copiedPrefix" : "independent",
"localBoundary": shape.ownedSuffix == nil ? "false" : "true",
"localBoundary": ownedSuffix == nil ? "false" : "true",
"parentConfirmedBoundary": parentConfirmedLocalBoundary ? "true" : "false",
"suppressedUnownedPrefix": suppressUnownedCopiedPrefix ? "true" : "false",
"sessionMetadataCount": String(observations.count(where: {
if case .sessionMetadata = $0.kind {
Expand All @@ -2644,7 +2666,7 @@ enum CostUsageScanner {
])
try configureForkAccountingIfReady()
for buffered in pendingSubagentLines
where shape.ownedSuffix.map({ buffered.lineIndex >= $0.startLineIndex }) ?? true
where ownedSuffix.map({ buffered.lineIndex >= $0.startLineIndex }) ?? true
{
try processFastLine(buffered.line)
}
Expand Down Expand Up @@ -2675,8 +2697,8 @@ enum CostUsageScanner {
sessionId: sessionId,
forkedFromId: forkedFromId,
dependsOnParentTotals: forkedFromId != nil
&& subagentCounterSemantics != .independent
&& !usesLocalSubagentBoundary,
&& (candidateBoundaryDependsOnParentTotals
|| (subagentCounterSemantics != .independent && !usesLocalSubagentBoundary)),
projectPath: projectPath,
rows: rows)
}
Expand Down
Loading