[codex] Add local tool trace toggle (#806)

* test: harden tool approval browser contract

* test: cover tool trace display edge cases

* test: cover resumed tool trace edge cases

* feat: hide tool traces by default

* Add local tool trace toggle

---------

Co-authored-by: Zhicheng Han <zhicheng.han@mathematik.uni-goettingen.de>
This commit is contained in:
ekko
2026-05-17 09:01:59 +08:00
committed by GitHub
parent 569ddc28da
commit 0c2bafc619
19 changed files with 975 additions and 29 deletions
@@ -6,10 +6,12 @@ import { useChatStore } from "@/stores/hermes/chat";
import thinkingVideoLight from "@/assets/thinking-light.mp4";
import thinkingVideoDark from "@/assets/thinking-dark.mp4";
import { useTheme } from "@/composables/useTheme";
import { useToolTraceVisibility } from "@/composables/useToolTraceVisibility";
const chatStore = useChatStore();
const { t } = useI18n();
const { isDark } = useTheme();
const { toolTraceVisible } = useToolTraceVisibility();
const listRef = ref<HTMLElement>();
function formatTokens(n: number): string {
@@ -41,9 +43,16 @@ const currentToolCalls = computed(() => {
return [...tools].reverse();
});
const displayMessages = computed(() =>
chatStore.messages.filter((m) => {
if (m.role === "tool") return false;
const visibleToolCalls = computed(() =>
toolTraceVisible.value ? currentToolCalls.value.filter((tool) => !!tool.toolName) : [],
);
const displayMessages = computed(() => {
const currentToolIds = new Set(currentToolCalls.value.map((tool) => tool.id));
return chatStore.messages.filter((m) => {
if (m.role === "tool") {
return toolTraceVisible.value && !!m.toolName && !(chatStore.isRunActive && currentToolIds.has(m.id));
}
if (
m.role === "assistant" &&
m.isStreaming &&
@@ -54,8 +63,8 @@ const displayMessages = computed(() =>
return false;
}
return true;
}),
);
});
});
const queuedMessages = computed(() => {
const sid = chatStore.activeSessionId;
@@ -171,7 +180,7 @@ watch(currentToolCalls, () => {
playsinline
class="thinking-video"
/>
<div v-if="currentToolCalls.length > 0 || chatStore.compressionState || chatStore.abortState" class="tool-calls-panel">
<div v-if="visibleToolCalls.length > 0 || chatStore.compressionState || chatStore.abortState" class="tool-calls-panel">
<!-- Abort indicator -->
<div v-if="chatStore.abortState" class="tool-call-item compression-item">
<svg
@@ -254,7 +263,7 @@ watch(currentToolCalls, () => {
</div>
<!-- Tool calls -->
<div
v-for="tc in currentToolCalls"
v-for="tc in visibleToolCalls"
:key="tc.id"
class="tool-call-item"
>