+ {compactPresentation && successful && result !== undefined && (
+
+ )}
{t("toolInput")}
@@ -953,13 +977,21 @@ const ToolPart = ({
);
};
+const AgentTraceToolGroup = ({ children }: { children?: ReactNode }) => (
+
+
+ {children}
+
+
+);
+
const ChainOfThoughtLayout = ({ children }: { children?: ReactNode }) => (
-
+
{children}
);
-const AssistantChainOfThought = () => {
+const AssistantChainOfThought = ({ children }: { children?: ReactNode }) => {
const t = useScopedI18n("common.assistant");
const contentId = useId();
const { collapsed: preferredCollapsed, setCollapsed: setPreferredCollapsed } = useContext(ReasoningVisibilityContext);
@@ -988,9 +1020,7 @@ const AssistantChainOfThought = () => {
-
+ {children}
);
@@ -1512,6 +1542,64 @@ const ConversationTurn = ({
);
};
+const ConversationContextBreakdown = ({ breakdown }: { breakdown: AssistantContextBreakdown }) => {
+ const t = useScopedI18n("common.assistant");
+ const hasContext = breakdown.percentage !== undefined;
+ const categories = [
+ { label: t("usage.input"), value: breakdown.inputTokens },
+ { label: t("usage.cached"), value: breakdown.cachedInputTokens },
+ { label: t("usage.output"), value: breakdown.outputTokens },
+ { label: t("usage.reasoning"), value: breakdown.reasoningTokens },
+ ];
+
+ return (
+
+
+ {hasContext ? `${breakdown.percentage}%` : "–"}
+
+ }
+ />
+
+ {[
+ { label: t("usage.used"), value: breakdown.contextUsed },
+ { label: t("usage.remaining"), value: breakdown.remaining },
+ { label: t("usage.capacity"), value: breakdown.contextLength },
+ ].map((item) => (
+
+
+ {item.label}
+
+
+ {item.value?.toLocaleString() ?? t("usage.notReported")}
+
+
+ ))}
+
+
+ {categories.map((category) => (
+
+
+ {category.label}
+
+
+ {category.value?.toLocaleString() ?? t("usage.notReported")}
+
+
+ ))}
+
+
+ );
+};
+
const ConversationContext = () => {
const t = useScopedI18n("common.assistant");
const [opened, setOpened] = useState(false);
@@ -1529,12 +1617,11 @@ const ConversationContext = () => {
[messages],
);
const usage = useMemo(() => getAssistantConversationUsage(metadata), [metadata]);
+ const breakdown = useMemo(() => getAssistantContextBreakdown(usage), [usage]);
const hasTokenUsage = usage.turns.some((turn) => turn.totalTokens !== undefined);
const hasCost = usage.turns.some((turn) => turn.cost !== undefined);
- const hasContext = usage.contextUsed !== undefined && usage.contextLength !== undefined;
- const contextPercentage = hasContext
- ? Math.min(100, Math.round(((usage.contextUsed ?? 0) / Math.max(usage.contextLength ?? 1, 1)) * 100))
- : 0;
+ const hasContext = breakdown.percentage !== undefined;
+ const contextPercentage = breakdown.percentage ?? 0;
const quickLabel = [
hasTokenUsage ? `${usage.totalTokens.toLocaleString()} ${t("usage.tokens")}` : undefined,
hasCost ? formatCost(usage.cost) : undefined,
@@ -1607,20 +1694,16 @@ const ConversationContext = () => {
- {t("usage.used")}
+ {t("usage.agentSteps")}
- {usage.contextUsed?.toLocaleString() ?? t("usage.notReported")}
+ {usage.turns.reduce((total, turn) => total + turn.telemetry.steps.length, 0).toLocaleString()}
- {usage.contextLength !== undefined && (
-
- / {usage.contextLength.toLocaleString()}
-
- )}