@@ -1487,3 +1487,170 @@ These tables should render cleanly without any disruptive copy or download actio
14871487 return < AppWithTableMocks /> ;
14881488 } ,
14891489} ;
1490+
1491+ /**
1492+ * Story showing the auto-compaction warning when context usage is approaching the threshold.
1493+ * The warning appears above the chat input when usage is >= 60% (threshold 70% minus 10% warning advance).
1494+ * claude-sonnet-4-5 has max_input_tokens: 200,000, so we set usage to ~130,000 tokens (65%) to trigger warning.
1495+ */
1496+ export const AutoCompactionWarning : Story = {
1497+ render : ( ) => {
1498+ const workspaceId = "ws-high-usage" ;
1499+
1500+ const projects = new Map < string , ProjectConfig > ( [
1501+ [
1502+ "/home/user/projects/my-app" ,
1503+ {
1504+ workspaces : [
1505+ { path : "/home/user/.mux/src/my-app/feature" , id : workspaceId , name : "main" } ,
1506+ ] ,
1507+ } ,
1508+ ] ,
1509+ ] ) ;
1510+
1511+ const workspaces : FrontendWorkspaceMetadata [ ] = [
1512+ {
1513+ id : workspaceId ,
1514+ name : "main" ,
1515+ projectPath : "/home/user/projects/my-app" ,
1516+ projectName : "my-app" ,
1517+ namedWorkspacePath : "/home/user/.mux/src/my-app/feature" ,
1518+ runtimeConfig : DEFAULT_RUNTIME_CONFIG ,
1519+ createdAt : new Date ( NOW - 3600000 ) . toISOString ( ) ,
1520+ } ,
1521+ ] ;
1522+
1523+ const AppWithHighUsage : React . FC = ( ) => {
1524+ const initialized = useRef ( false ) ;
1525+ if ( ! initialized . current ) {
1526+ // Enable auto-compaction for this workspace (enabled per-workspace, threshold per-model)
1527+ localStorage . setItem ( `autoCompaction:enabled:${ workspaceId } ` , "true" ) ;
1528+ localStorage . setItem ( `autoCompaction:threshold:claude-sonnet-4-5` , "70" ) ;
1529+
1530+ setupMockAPI ( {
1531+ projects,
1532+ workspaces,
1533+ apiOverrides : {
1534+ tokenizer : {
1535+ countTokens : ( ) => Promise . resolve ( 100 ) ,
1536+ countTokensBatch : ( _model , texts ) => Promise . resolve ( texts . map ( ( ) => 100 ) ) ,
1537+ calculateStats : ( ) =>
1538+ Promise . resolve ( {
1539+ consumers : [ ] ,
1540+ totalTokens : 0 ,
1541+ model : "claude-sonnet-4-5" ,
1542+ tokenizerName : "claude" ,
1543+ usageHistory : [ ] ,
1544+ } ) ,
1545+ } ,
1546+ providers : {
1547+ setProviderConfig : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1548+ setModels : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1549+ getConfig : ( ) =>
1550+ Promise . resolve (
1551+ { } as Record < string , { apiKeySet : boolean ; baseUrl ?: string ; models ?: string [ ] } >
1552+ ) ,
1553+ list : ( ) => Promise . resolve ( [ "anthropic" ] ) ,
1554+ } ,
1555+ workspace : {
1556+ create : ( projectPath : string , branchName : string ) =>
1557+ Promise . resolve ( {
1558+ success : true ,
1559+ metadata : {
1560+ id : Math . random ( ) . toString ( 36 ) . substring ( 2 , 12 ) ,
1561+ name : branchName ,
1562+ projectPath,
1563+ projectName : projectPath . split ( "/" ) . pop ( ) ?? "project" ,
1564+ namedWorkspacePath : `/mock/workspace/${ branchName } ` ,
1565+ runtimeConfig : DEFAULT_RUNTIME_CONFIG ,
1566+ } ,
1567+ } ) ,
1568+ list : ( ) => Promise . resolve ( workspaces ) ,
1569+ rename : ( wsId : string ) =>
1570+ Promise . resolve ( { success : true , data : { newWorkspaceId : wsId } } ) ,
1571+ remove : ( ) => Promise . resolve ( { success : true } ) ,
1572+ fork : ( ) => Promise . resolve ( { success : false , error : "Not implemented in mock" } ) ,
1573+ openTerminal : ( ) => Promise . resolve ( undefined ) ,
1574+ onChat : ( wsId , callback ) => {
1575+ if ( wsId === workspaceId ) {
1576+ setTimeout ( ( ) => {
1577+ // User message
1578+ callback ( {
1579+ id : "msg-1" ,
1580+ role : "user" ,
1581+ parts : [ { type : "text" , text : "Help me with this large codebase" } ] ,
1582+ metadata : {
1583+ historySequence : 1 ,
1584+ timestamp : STABLE_TIMESTAMP - 60000 ,
1585+ } ,
1586+ } ) ;
1587+
1588+ // Assistant message with HIGH usage to trigger compaction warning
1589+ // 130,000 tokens = 65% of 200,000 max, which is above 60% warning threshold
1590+ callback ( {
1591+ id : "msg-2" ,
1592+ role : "assistant" ,
1593+ parts : [
1594+ {
1595+ type : "text" ,
1596+ text : "I've analyzed the codebase. The context window is getting full - notice the compaction warning below!" ,
1597+ } ,
1598+ ] ,
1599+ metadata : {
1600+ historySequence : 2 ,
1601+ timestamp : STABLE_TIMESTAMP ,
1602+ model : "claude-sonnet-4-5" ,
1603+ usage : {
1604+ inputTokens : 125000 , // High input to trigger warning
1605+ outputTokens : 5000 ,
1606+ totalTokens : 130000 ,
1607+ } ,
1608+ duration : 5000 ,
1609+ } ,
1610+ } ) ;
1611+
1612+ callback ( { type : "caught-up" } ) ;
1613+ } , 100 ) ;
1614+ }
1615+ return ( ) => undefined ;
1616+ } ,
1617+ onMetadata : ( ) => ( ) => undefined ,
1618+ activity : {
1619+ list : ( ) => Promise . resolve ( { } ) ,
1620+ subscribe : ( ) => ( ) => undefined ,
1621+ } ,
1622+ sendMessage : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1623+ resumeStream : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1624+ interruptStream : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1625+ clearQueue : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1626+ truncateHistory : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1627+ replaceChatHistory : ( ) => Promise . resolve ( { success : true , data : undefined } ) ,
1628+ getInfo : ( ) => Promise . resolve ( null ) ,
1629+ executeBash : ( ) =>
1630+ Promise . resolve ( {
1631+ success : true ,
1632+ data : { success : true , output : "" , exitCode : 0 , wall_duration_ms : 0 } ,
1633+ } ) ,
1634+ } ,
1635+ } ,
1636+ } ) ;
1637+
1638+ localStorage . setItem (
1639+ "selectedWorkspace" ,
1640+ JSON . stringify ( {
1641+ workspaceId : workspaceId ,
1642+ projectPath : "/home/user/projects/my-app" ,
1643+ projectName : "my-app" ,
1644+ namedWorkspacePath : "/home/user/.mux/src/my-app/feature" ,
1645+ } )
1646+ ) ;
1647+
1648+ initialized . current = true ;
1649+ }
1650+
1651+ return < AppLoader /> ;
1652+ } ;
1653+
1654+ return < AppWithHighUsage /> ;
1655+ } ,
1656+ } ;
0 commit comments