Skip to content

Commit b0bb5c7

Browse files
committed
fix(chatui): reasoning summary
1 parent 0da1748 commit b0bb5c7

6 files changed

Lines changed: 79 additions & 10 deletions

File tree

dashboard/src/components/chat/ReasoningSidebar.vue

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<transition name="slide-left">
33
<aside v-if="modelValue" class="reasoning-sidebar">
44
<div class="reasoning-sidebar-header">
5-
<div class="reasoning-sidebar-title">{{ tm("reasoning.thinking") }}</div>
5+
<div class="reasoning-sidebar-title">{{ reasoningTitle }}</div>
66
<v-btn icon="mdi-close" size="small" variant="text" @click="close" />
77
</div>
88

@@ -14,19 +14,24 @@
1414
:is-dark="isDark"
1515
/>
1616
<div v-else class="reasoning-sidebar-empty">
17-
{{ tm("reasoning.thinking") }}
17+
{{ reasoningTitle }}
1818
</div>
1919
</div>
2020
</aside>
2121
</transition>
2222
</template>
2323

2424
<script setup lang="ts">
25-
import type { MessagePart } from "@/composables/useMessages";
25+
import { computed } from "vue";
26+
import {
27+
reasoningActivityCounts,
28+
reasoningActivityTitle,
29+
type MessagePart,
30+
} from "@/composables/useMessages";
2631
import { useModuleI18n } from "@/i18n/composables";
2732
import ReasoningTimeline from "@/components/chat/message_list_comps/ReasoningTimeline.vue";
2833
29-
defineProps<{
34+
const props = defineProps<{
3035
modelValue: boolean;
3136
parts: MessagePart[];
3237
reasoning?: string;
@@ -39,6 +44,14 @@ const emit = defineEmits<{
3944
4045
const { tm } = useModuleI18n("features/chat");
4146
47+
const activityCounts = computed(() =>
48+
reasoningActivityCounts(props.parts, props.reasoning || ""),
49+
);
50+
51+
const reasoningTitle = computed(() =>
52+
reasoningActivityTitle(activityCounts.value, tm),
53+
);
54+
4255
function close() {
4356
emit("update:modelValue", false);
4457
}

dashboard/src/components/chat/message_list_comps/ReasoningBlock.vue

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
@click="handlePrimaryAction"
88
>
99
<span class="reasoning-title">
10-
{{ tm("reasoning.thinking") }}
10+
{{ reasoningTitle }}
1111
</span>
1212
<v-icon
1313
size="22"
@@ -40,7 +40,11 @@
4040

4141
<script setup lang="ts">
4242
import { computed, onBeforeUnmount, ref, watch } from "vue";
43-
import type { MessagePart } from "@/composables/useMessages";
43+
import {
44+
reasoningActivityCounts,
45+
reasoningActivityTitle,
46+
type MessagePart,
47+
} from "@/composables/useMessages";
4448
import { useModuleI18n } from "@/i18n/composables";
4549
import ReasoningTimeline from "@/components/chat/message_list_comps/ReasoningTimeline.vue";
4650
@@ -75,6 +79,14 @@ const renderParts = computed<MessagePart[]>(() => {
7579
7680
const openInSidebar = computed(() => Boolean(props.openInSidebar));
7781
82+
const activityCounts = computed(() =>
83+
reasoningActivityCounts(renderParts.value, props.reasoning || ""),
84+
);
85+
86+
const reasoningTitle = computed(() =>
87+
reasoningActivityTitle(activityCounts.value, tm),
88+
);
89+
7890
const thinkingText = computed(() =>
7991
renderParts.value
8092
.filter((part) => part.type === "think")
@@ -214,14 +226,11 @@ onBeforeUnmount(() => {
214226
color: rgba(var(--v-theme-on-surface), 0.88);
215227
}
216228
217-
.reasoning-header--trigger {
218-
align-items: flex-start;
219-
}
220-
221229
.reasoning-icon {
222230
color: currentcolor;
223231
transition: transform 0.2s ease;
224232
flex-shrink: 0;
233+
align-self: center;
225234
}
226235
227236
.reasoning-title {

dashboard/src/composables/useMessages.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,44 @@ export function extractReasoningText(
794794
return text || legacyReasoning;
795795
}
796796

797+
export function reasoningActivityCounts(
798+
parts: MessagePart[] | unknown,
799+
legacyReasoning = "",
800+
) {
801+
const normalizedParts = Array.isArray(parts)
802+
? parts
803+
: normalizeMessageParts(parts, legacyReasoning);
804+
let thinkCount = 0;
805+
let toolCount = 0;
806+
807+
for (const part of normalizedParts) {
808+
if (part.type === "think" && String(part.think || "").trim()) {
809+
thinkCount += 1;
810+
}
811+
if (part.type === "tool_call" && Array.isArray(part.tool_calls)) {
812+
toolCount += part.tool_calls.length;
813+
}
814+
}
815+
816+
return { thinkCount, toolCount };
817+
}
818+
819+
export function reasoningActivityTitle(
820+
counts: ReturnType<typeof reasoningActivityCounts>,
821+
tm: (key: string, params?: Record<string, string | number>) => string,
822+
) {
823+
return [
824+
counts.thinkCount > 0
825+
? tm("reasoning.thinkSummary", { count: counts.thinkCount })
826+
: "",
827+
counts.toolCount > 0
828+
? tm("reasoning.toolSummary", { count: counts.toolCount })
829+
: "",
830+
]
831+
.filter(Boolean)
832+
.join(tm("reasoning.summarySeparator")) || tm("reasoning.thinking");
833+
}
834+
797835
export function thinkingParts(content: ChatContent): MessagePart[] {
798836
const firstThinkingBlock = messageBlocks(content).find(
799837
(block) => block.kind === "thinking",

dashboard/src/i18n/locales/en-US/features/chat.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
},
115115
"reasoning": {
116116
"thinking": "Thinking Process",
117+
"summarySeparator": ", ",
118+
"thinkSummary": "Thought {count} times",
119+
"toolSummary": "used {count} tools",
117120
"think": "Thinking",
118121
"toolUsed": "Using Tool"
119122
},

dashboard/src/i18n/locales/ru-RU/features/chat.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
},
115115
"reasoning": {
116116
"thinking": "Рассуждение",
117+
"summarySeparator": ", ",
118+
"thinkSummary": "Размышлений: {count}",
119+
"toolSummary": "использований инструментов: {count}",
117120
"think": "Размышление",
118121
"toolUsed": "Использование инструмента"
119122
},

dashboard/src/i18n/locales/zh-CN/features/chat.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@
114114
},
115115
"reasoning": {
116116
"thinking": "思考过程",
117+
"summarySeparator": "",
118+
"thinkSummary": "思考了 {count} 次",
119+
"toolSummary": "使用了 {count} 次工具",
117120
"think": "思考",
118121
"toolUsed": "使用工具"
119122
},

0 commit comments

Comments
 (0)