Skip to content

Commit b816aed

Browse files
Sync public snapshot from freebuff-private
Source: CodebuffAI/freebuff-private@77bccf5c423c70981b49738e0a07d174868741fd
1 parent 324e4ba commit b816aed

3 files changed

Lines changed: 45 additions & 0 deletions

File tree

cli/src/hooks/use-freebuff-session.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ function nextDelayMs(next: FreebuffSessionResponse): number | null {
9696
case 'ip_capped':
9797
case 'model_unavailable':
9898
case 'premium_slot_taken':
99+
case 'purchase_claim_released':
100+
case 'purchase_in_use':
101+
case 'purchase_capacity':
99102
return null
100103
}
101104
}

common/src/constants/freebuff-desktop-sessions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,7 @@ export function occupiesFreebuffDesktopSlot(
6969

7070
/** Idle time after which Desktop may reclaim a constrained session slot. */
7171
export const FREEBUFF_DESKTOP_IDLE_RELEASE_MS = 10 * 60 * 1000
72+
73+
/** Versioned opt-in: instance ids become single-use execution claims. */
74+
export const FREEBUFF_PURCHASE_CONTINUITY_HEADER =
75+
'x-freebuff-purchase-continuity'

common/src/types/freebuff-session.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,17 @@ export type FreebuffSessionAdmissionResponse = (
953953
/** The way out of this refusal, when there is one to sell. */
954954
upgrade?: FreebuffUpgradeHint
955955
}
956+
| {
957+
/** Retired single-use Desktop claim; persist a new id before retrying. */
958+
status: 'purchase_claim_released'
959+
accessTier?: FreebuffAccessTier
960+
}
961+
| {
962+
status: 'purchase_in_use' | 'purchase_capacity'
963+
accessTier?: FreebuffAccessTier
964+
requestedModel: string
965+
currentInstanceId: string
966+
}
956967
| {
957968
/** Freebuff Desktop only: every slot-bound session is occupied. Free
958969
* accounts get one slot-bound and three multi-tab sessions; subscribers
@@ -972,6 +983,10 @@ export type FreebuffSessionAdmissionResponse = (
972983
currentInstanceId: string
973984
}
974985
) & {
986+
/** Unexpired Desktop purchases, including occupied hours. Picker metadata;
987+
* admission still checks ownership, liveness, and capacity atomically. */
988+
desktopPurchases?: FreebuffDesktopPurchaseInfo[]
989+
desktopRefunds?: FreebuffDesktopRefundInfo[]
975990
/** Multi-session Desktop responses only. Counts live, unexpired rows across
976991
* all Desktop processes for this user. */
977992
desktopSessionCounts?: FreebuffDesktopSessionCounts
@@ -987,8 +1002,31 @@ export type FreebuffSessionServerResponse =
9871002
* surfaces it as a 409 for fast in-flight feedback. */
9881003
status: 'superseded'
9891004
desktopSessionCounts?: FreebuffDesktopSessionCounts
1005+
desktopPurchases?: FreebuffDesktopPurchaseInfo[]
1006+
desktopRefunds?: FreebuffDesktopRefundInfo[]
9901007
}
9911008

1009+
/** Emitted only after the reversal ledger entry and purchase marker commit. */
1010+
export interface FreebuffDesktopRefundInfo {
1011+
/** Durable execution claims belonging to this purchase; omitted by older APIs. */
1012+
claimInstanceIds?: string[]
1013+
purchaseId: string
1014+
model: string
1015+
amount: number
1016+
walletAmount: number
1017+
/** Refunded bonus retired in the same settlement; absent on older APIs. */
1018+
expiredBonusAmount?: number
1019+
refundedAt: string
1020+
/** Original debit's accounting instant; identifies the daily pool restored. */
1021+
poolDate: string
1022+
}
1023+
1024+
export interface FreebuffDesktopPurchaseInfo {
1025+
model: string
1026+
expiresAt: string
1027+
holderInstanceId?: string
1028+
}
1029+
9921030
/**
9931031
* The session gate on `/api/v1/chat/completions`, as a wire contract.
9941032
*

0 commit comments

Comments
 (0)