mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-15 16:41:11 -07:00
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Jacob Richman <jacob314@gmail.com>
144 lines
3.0 KiB
TypeScript
144 lines
3.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import React, {
|
|
createContext,
|
|
useCallback,
|
|
useContext,
|
|
useState,
|
|
useMemo,
|
|
useEffect,
|
|
} from 'react';
|
|
|
|
import {
|
|
uiTelemetryService,
|
|
SessionMetrics,
|
|
ModelMetrics,
|
|
sessionId,
|
|
} from '@google/gemini-cli-core';
|
|
|
|
// --- Interface Definitions ---
|
|
|
|
export type { SessionMetrics, ModelMetrics };
|
|
|
|
export interface SessionStatsState {
|
|
sessionId: string;
|
|
sessionStartTime: Date;
|
|
metrics: SessionMetrics;
|
|
lastPromptTokenCount: number;
|
|
promptCount: number;
|
|
}
|
|
|
|
export interface ComputedSessionStats {
|
|
totalApiTime: number;
|
|
totalToolTime: number;
|
|
agentActiveTime: number;
|
|
apiTimePercent: number;
|
|
toolTimePercent: number;
|
|
cacheEfficiency: number;
|
|
totalDecisions: number;
|
|
successRate: number;
|
|
agreementRate: number;
|
|
totalCachedTokens: number;
|
|
totalPromptTokens: number;
|
|
totalLinesAdded: number;
|
|
totalLinesRemoved: number;
|
|
}
|
|
|
|
// Defines the final "value" of our context, including the state
|
|
// and the functions to update it.
|
|
interface SessionStatsContextValue {
|
|
stats: SessionStatsState;
|
|
startNewPrompt: () => void;
|
|
getPromptCount: () => number;
|
|
}
|
|
|
|
// --- Context Definition ---
|
|
|
|
const SessionStatsContext = createContext<SessionStatsContextValue | undefined>(
|
|
undefined,
|
|
);
|
|
|
|
// --- Provider Component ---
|
|
|
|
export const SessionStatsProvider: React.FC<{ children: React.ReactNode }> = ({
|
|
children,
|
|
}) => {
|
|
const [stats, setStats] = useState<SessionStatsState>({
|
|
sessionId,
|
|
sessionStartTime: new Date(),
|
|
metrics: uiTelemetryService.getMetrics(),
|
|
lastPromptTokenCount: 0,
|
|
promptCount: 0,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const handleUpdate = ({
|
|
metrics,
|
|
lastPromptTokenCount,
|
|
}: {
|
|
metrics: SessionMetrics;
|
|
lastPromptTokenCount: number;
|
|
}) => {
|
|
setStats((prevState) => ({
|
|
...prevState,
|
|
metrics,
|
|
lastPromptTokenCount,
|
|
}));
|
|
};
|
|
|
|
uiTelemetryService.on('update', handleUpdate);
|
|
// Set initial state
|
|
handleUpdate({
|
|
metrics: uiTelemetryService.getMetrics(),
|
|
lastPromptTokenCount: uiTelemetryService.getLastPromptTokenCount(),
|
|
});
|
|
|
|
return () => {
|
|
uiTelemetryService.off('update', handleUpdate);
|
|
};
|
|
}, []);
|
|
|
|
const startNewPrompt = useCallback(() => {
|
|
setStats((prevState) => ({
|
|
...prevState,
|
|
promptCount: prevState.promptCount + 1,
|
|
}));
|
|
}, []);
|
|
|
|
const getPromptCount = useCallback(
|
|
() => stats.promptCount,
|
|
[stats.promptCount],
|
|
);
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
stats,
|
|
startNewPrompt,
|
|
getPromptCount,
|
|
}),
|
|
[stats, startNewPrompt, getPromptCount],
|
|
);
|
|
|
|
return (
|
|
<SessionStatsContext.Provider value={value}>
|
|
{children}
|
|
</SessionStatsContext.Provider>
|
|
);
|
|
};
|
|
|
|
// --- Consumer Hook ---
|
|
|
|
export const useSessionStats = () => {
|
|
const context = useContext(SessionStatsContext);
|
|
if (context === undefined) {
|
|
throw new Error(
|
|
'useSessionStats must be used within a SessionStatsProvider',
|
|
);
|
|
}
|
|
return context;
|
|
};
|