feat(gateway,cli,types): wire token usage, model info, and thinking levels

Gateway:
- Emit session:info on session creation with provider, model, thinking level
- Include SessionUsagePayload in agent:end with token stats, cost, context usage
- Handle set:thinking client event to cycle thinking levels
- Respond with updated session:info after thinking level change

Types (@mosaic/types):
- Add SessionUsagePayload (tokens, cost, context) to AgentEndPayload
- Add SessionInfoPayload (provider, model, thinking level, available levels)
- Add SetThinkingPayload and set:thinking to ClientToServerEvents
- Add session:info to ServerToClientEvents

CLI TUI:
- useSocket now tracks tokenUsage, modelName, providerName, thinkingLevel
- Updates from both session:info and agent:end usage payload
- Ctrl+T cycles thinking level via set:thinking socket event
- Footer shows thinking level next to model (e.g. 'claude-opus-4-6 • medium')
- Token stats populate with real ↑in ↓out Rcache Wcache $cost ctx%
This commit is contained in:
2026-03-15 14:05:33 -05:00
parent 867e6097b0
commit a061a64fff
6 changed files with 195 additions and 18 deletions

View File

@@ -23,10 +23,22 @@ export function TuiApp({ gatewayUrl, conversationId, sessionCookie }: TuiAppProp
initialConversationId: conversationId,
});
useInput((_ch, key) => {
if (key.ctrl && _ch === 'c') {
useInput((ch, key) => {
if (key.ctrl && ch === 'c') {
exit();
}
// Ctrl+T: cycle thinking level
if (key.ctrl && ch === 't') {
const levels = socket.availableThinkingLevels;
if (levels.length > 0) {
const currentIdx = levels.indexOf(socket.thinkingLevel);
const nextIdx = (currentIdx + 1) % levels.length;
const next = levels[nextIdx];
if (next) {
socket.setThinkingLevel(next);
}
}
}
});
return (
@@ -54,6 +66,7 @@ export function TuiApp({ gatewayUrl, conversationId, sessionCookie }: TuiAppProp
connecting={socket.connecting}
modelName={socket.modelName}
providerName={socket.providerName}
thinkingLevel={socket.thinkingLevel}
/>
</Box>
);