summaryrefslogtreecommitdiffhomepage
path: root/packages/ui
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-17 15:57:46 -0600
committerAdam <[email protected]>2026-02-17 15:57:50 -0600
commite345b89ce56cf7fbd0c58c5f882eaf9a8ebc8fb0 (patch)
tree7c93909efb4a730a769b953aec73aaeabb86743d /packages/ui
parent26c7b240bac7ae9c4b9d0d4d50ae288479f861c3 (diff)
downloadopencode-e345b89ce56cf7fbd0c58c5f882eaf9a8ebc8fb0.tar.gz
opencode-e345b89ce56cf7fbd0c58c5f882eaf9a8ebc8fb0.zip
fix(app): better tool call batching
Diffstat (limited to 'packages/ui')
-rw-r--r--packages/ui/src/components/message-part.tsx161
-rw-r--r--packages/ui/src/components/session-turn.tsx25
-rw-r--r--packages/ui/src/i18n/ar.ts3
-rw-r--r--packages/ui/src/i18n/br.ts3
-rw-r--r--packages/ui/src/i18n/bs.ts3
-rw-r--r--packages/ui/src/i18n/da.ts3
-rw-r--r--packages/ui/src/i18n/de.ts3
-rw-r--r--packages/ui/src/i18n/en.ts3
-rw-r--r--packages/ui/src/i18n/es.ts3
-rw-r--r--packages/ui/src/i18n/fr.ts3
-rw-r--r--packages/ui/src/i18n/ja.ts3
-rw-r--r--packages/ui/src/i18n/ko.ts3
-rw-r--r--packages/ui/src/i18n/no.ts3
-rw-r--r--packages/ui/src/i18n/pl.ts3
-rw-r--r--packages/ui/src/i18n/ru.ts3
-rw-r--r--packages/ui/src/i18n/th.ts3
-rw-r--r--packages/ui/src/i18n/zh.ts3
-rw-r--r--packages/ui/src/i18n/zht.ts3
18 files changed, 187 insertions, 47 deletions
diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx
index 4db5508bf..24ae16a31 100644
--- a/packages/ui/src/components/message-part.tsx
+++ b/packages/ui/src/components/message-part.tsx
@@ -117,6 +117,7 @@ function createThrottledValue(getValue: () => string) {
createEffect(() => {
const next = getValue()
const now = Date.now()
+
const remaining = TEXT_RENDER_THROTTLE_MS - (now - last)
if (remaining <= 0) {
if (timeout) {
@@ -250,6 +251,126 @@ export function getToolInfo(tool: string, input: any = {}): ToolInfo {
}
const CONTEXT_GROUP_TOOLS = new Set(["read", "glob", "grep", "list"])
+const HIDDEN_TOOLS = new Set(["todowrite", "todoread"])
+
+function list<T>(value: T[] | undefined | null, fallback: T[]) {
+ if (Array.isArray(value)) return value
+ return fallback
+}
+
+function renderable(part: PartType) {
+ if (part.type === "tool") {
+ if (HIDDEN_TOOLS.has(part.tool)) return false
+ if (part.tool === "question") return part.state.status !== "pending" && part.state.status !== "running"
+ return true
+ }
+ if (part.type === "text") return !!part.text?.trim()
+ if (part.type === "reasoning") return !!part.text?.trim()
+ return !!PART_MAPPING[part.type]
+}
+
+export function AssistantParts(props: {
+ messages: AssistantMessage[]
+ showAssistantCopyPartID?: string | null
+ working?: boolean
+}) {
+ const data = useData()
+ const emptyParts: PartType[] = []
+
+ const grouped = createMemo(() => {
+ const keys: string[] = []
+ const items: Record<
+ string,
+ { type: "part"; part: PartType; message: AssistantMessage } | { type: "context"; parts: ToolPart[] }
+ > = {}
+ const push = (
+ key: string,
+ item: { type: "part"; part: PartType; message: AssistantMessage } | { type: "context"; parts: ToolPart[] },
+ ) => {
+ keys.push(key)
+ items[key] = item
+ }
+
+ const parts = props.messages.flatMap((message) =>
+ list(data.store.part?.[message.id], emptyParts)
+ .filter(renderable)
+ .map((part) => ({ message, part })),
+ )
+
+ let start = -1
+
+ const flush = (end: number) => {
+ if (start < 0) return
+ const first = parts[start]
+ const last = parts[end]
+ if (!first || !last) {
+ start = -1
+ return
+ }
+ push(`context:${first.part.id}`, {
+ type: "context",
+ parts: parts
+ .slice(start, end + 1)
+ .map((x) => x.part)
+ .filter((part): part is ToolPart => isContextGroupTool(part)),
+ })
+ start = -1
+ }
+
+ parts.forEach((item, index) => {
+ if (isContextGroupTool(item.part)) {
+ if (start < 0) start = index
+ return
+ }
+
+ flush(index - 1)
+ push(`part:${item.message.id}:${item.part.id}`, { type: "part", part: item.part, message: item.message })
+ })
+
+ flush(parts.length - 1)
+
+ return { keys, items }
+ })
+
+ const last = createMemo(() => grouped().keys.at(-1))
+
+ return (
+ <For each={grouped().keys}>
+ {(key) => {
+ const item = createMemo(() => grouped().items[key])
+ const ctx = createMemo(() => {
+ const value = item()
+ if (!value) return
+ if (value.type !== "context") return
+ return value
+ })
+ const part = createMemo(() => {
+ const value = item()
+ if (!value) return
+ if (value.type !== "part") return
+ return value
+ })
+ const tail = createMemo(() => last() === key)
+ return (
+ <>
+ <Show when={ctx()}>
+ {(entry) => <ContextToolGroup parts={entry().parts} busy={props.working && tail()} />}
+ </Show>
+ <Show when={part()}>
+ {(entry) => (
+ <Part
+ part={entry().part}
+ message={entry().message}
+ showAssistantCopyPartID={props.showAssistantCopyPartID}
+ />
+ )}
+ </Show>
+ </>
+ )
+ }}
+ </For>
+ )
+}
function isContextGroupTool(part: PartType): part is ToolPart {
return part.type === "tool" && CONTEXT_GROUP_TOOLS.has(part.tool)
@@ -390,6 +511,8 @@ export function AssistantMessageDisplay(props: {
}
parts.forEach((part, index) => {
+ if (!renderable(part)) return
+
if (isContextGroupTool(part)) {
if (start < 0) start = index
return
@@ -408,31 +531,43 @@ export function AssistantMessageDisplay(props: {
<For each={grouped().keys}>
{(key) => {
const item = createMemo(() => grouped().items[key])
+ const ctx = createMemo(() => {
+ const value = item()
+ if (!value) return
+ if (value.type !== "context") return
+ return value
+ })
+ const part = createMemo(() => {
+ const value = item()
+ if (!value) return
+ if (value.type !== "part") return
+ return value
+ })
return (
- <Show when={item()}>
- {(value) => {
- const entry = value()
- if (entry.type === "context") return <ContextToolGroup parts={entry.parts} />
- return (
+ <>
+ <Show when={ctx()}>{(entry) => <ContextToolGroup parts={entry().parts} />}</Show>
+ <Show when={part()}>
+ {(entry) => (
<Part
- part={entry.part}
+ part={entry().part}
message={props.message}
showAssistantCopyPartID={props.showAssistantCopyPartID}
/>
- )
- }}
- </Show>
+ )}
+ </Show>
+ </>
)
}}
</For>
)
}
-function ContextToolGroup(props: { parts: ToolPart[] }) {
+function ContextToolGroup(props: { parts: ToolPart[]; busy?: boolean }) {
const i18n = useI18n()
const [open, setOpen] = createSignal(false)
- const pending = createMemo(() =>
- props.parts.some((part) => part.state.status === "pending" || part.state.status === "running"),
+ const pending = createMemo(
+ () =>
+ !!props.busy || props.parts.some((part) => part.state.status === "pending" || part.state.status === "running"),
)
const summary = createMemo(() => contextToolSummary(props.parts))
const details = createMemo(() => summary().join(", "))
@@ -445,7 +580,7 @@ function ContextToolGroup(props: { parts: ToolPart[] }) {
when={pending()}
fallback={
<span data-slot="context-tool-group-title">
- <span data-slot="context-tool-group-label">Gathered context</span>
+ <span data-slot="context-tool-group-label">{i18n.t("ui.sessionTurn.status.gatheredContext")}</span>
<Show when={details().length}>
<span data-slot="context-tool-group-summary">{details()}</span>
</Show>
diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx
index a99cc8d03..e4c0a2273 100644
--- a/packages/ui/src/components/session-turn.tsx
+++ b/packages/ui/src/components/session-turn.tsx
@@ -6,7 +6,7 @@ import { Binary } from "@opencode-ai/util/binary"
import { getDirectory, getFilename } from "@opencode-ai/util/path"
import { createMemo, createSignal, For, ParentProps, Show } from "solid-js"
import { Dynamic } from "solid-js/web"
-import { Message } from "./message-part"
+import { AssistantParts, Message } from "./message-part"
import { Card } from "./card"
import { Collapsible } from "./collapsible"
import { DiffChanges } from "./diff-changes"
@@ -91,13 +91,6 @@ function visible(part: PartType) {
return false
}
-function AssistantMessageItem(props: { message: AssistantMessage; showAssistantCopyPartID?: string | null }) {
- const data = useData()
- const emptyParts: PartType[] = []
- const msgParts = createMemo(() => list(data.store.part?.[props.message.id], emptyParts))
- return <Message message={props.message} parts={msgParts()} showAssistantCopyPartID={props.showAssistantCopyPartID} />
-}
-
export function SessionTurn(
props: ParentProps<{
sessionID: string
@@ -237,8 +230,7 @@ export function SessionTurn(
const working = createMemo(() => status().type !== "idle" && isLastUserMessage())
const assistantCopyPartID = createMemo(() => {
- if (!isLastUserMessage()) return null
- if (status().type !== "idle") return null
+ if (working()) return null
return showAssistantCopyPartID() ?? null
})
const assistantVisible = createMemo(() =>
@@ -281,14 +273,11 @@ export function SessionTurn(
</Show>
<Show when={assistantMessages().length > 0}>
<div data-slot="session-turn-assistant-content" aria-hidden={working()}>
- <For each={assistantMessages()}>
- {(assistantMessage) => (
- <AssistantMessageItem
- message={assistantMessage}
- showAssistantCopyPartID={assistantCopyPartID()}
- />
- )}
- </For>
+ <AssistantParts
+ messages={assistantMessages()}
+ showAssistantCopyPartID={assistantCopyPartID()}
+ working={working()}
+ />
</div>
</Show>
<Show when={edited() > 0}>
diff --git a/packages/ui/src/i18n/ar.ts b/packages/ui/src/i18n/ar.ts
index 6f8781ebf..aa30bbd57 100644
--- a/packages/ui/src/i18n/ar.ts
+++ b/packages/ui/src/i18n/ar.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "تفويض العمل",
"ui.sessionTurn.status.planning": "تخطيط الخطوات التالية",
- "ui.sessionTurn.status.gatheringContext": "جمع السياق",
+ "ui.sessionTurn.status.gatheringContext": "استكشاف...",
+ "ui.sessionTurn.status.gatheredContext": "تم الاستكشاف",
"ui.sessionTurn.status.searchingCodebase": "البحث في قاعدة التعليمات البرمجية",
"ui.sessionTurn.status.searchingWeb": "البحث في الويب",
"ui.sessionTurn.status.makingEdits": "إجراء تعديلات",
diff --git a/packages/ui/src/i18n/br.ts b/packages/ui/src/i18n/br.ts
index 89eb391f9..ca34e4a04 100644
--- a/packages/ui/src/i18n/br.ts
+++ b/packages/ui/src/i18n/br.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegando trabalho",
"ui.sessionTurn.status.planning": "Planejando próximos passos",
- "ui.sessionTurn.status.gatheringContext": "Coletando contexto",
+ "ui.sessionTurn.status.gatheringContext": "Explorando...",
+ "ui.sessionTurn.status.gatheredContext": "Explorado",
"ui.sessionTurn.status.searchingCodebase": "Pesquisando no código",
"ui.sessionTurn.status.searchingWeb": "Pesquisando na web",
"ui.sessionTurn.status.makingEdits": "Fazendo edições",
diff --git a/packages/ui/src/i18n/bs.ts b/packages/ui/src/i18n/bs.ts
index f1163758a..5b9a2443b 100644
--- a/packages/ui/src/i18n/bs.ts
+++ b/packages/ui/src/i18n/bs.ts
@@ -37,7 +37,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegiranje posla",
"ui.sessionTurn.status.planning": "Planiranje sljedećih koraka",
- "ui.sessionTurn.status.gatheringContext": "Prikupljanje konteksta",
+ "ui.sessionTurn.status.gatheringContext": "Istraživanje...",
+ "ui.sessionTurn.status.gatheredContext": "Istraženo",
"ui.sessionTurn.status.searchingCodebase": "Pretraživanje baze koda",
"ui.sessionTurn.status.searchingWeb": "Pretraživanje weba",
"ui.sessionTurn.status.makingEdits": "Pravljenje izmjena",
diff --git a/packages/ui/src/i18n/da.ts b/packages/ui/src/i18n/da.ts
index 8b42c1b80..4abdce547 100644
--- a/packages/ui/src/i18n/da.ts
+++ b/packages/ui/src/i18n/da.ts
@@ -32,7 +32,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegerer arbejde",
"ui.sessionTurn.status.planning": "Planlægger næste trin",
- "ui.sessionTurn.status.gatheringContext": "Indsamler kontekst",
+ "ui.sessionTurn.status.gatheringContext": "Udforsker...",
+ "ui.sessionTurn.status.gatheredContext": "Udforsket",
"ui.sessionTurn.status.searchingCodebase": "Søger i koden",
"ui.sessionTurn.status.searchingWeb": "Søger på nettet",
"ui.sessionTurn.status.makingEdits": "Laver ændringer",
diff --git a/packages/ui/src/i18n/de.ts b/packages/ui/src/i18n/de.ts
index c805b1e01..a2427332e 100644
--- a/packages/ui/src/i18n/de.ts
+++ b/packages/ui/src/i18n/de.ts
@@ -36,7 +36,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Arbeit delegieren",
"ui.sessionTurn.status.planning": "Nächste Schritte planen",
- "ui.sessionTurn.status.gatheringContext": "Kontext sammeln",
+ "ui.sessionTurn.status.gatheringContext": "Erkunden...",
+ "ui.sessionTurn.status.gatheredContext": "Erkundet",
"ui.sessionTurn.status.searchingCodebase": "Codebasis durchsuchen",
"ui.sessionTurn.status.searchingWeb": "Web durchsuchen",
"ui.sessionTurn.status.makingEdits": "Änderungen vornehmen",
diff --git a/packages/ui/src/i18n/en.ts b/packages/ui/src/i18n/en.ts
index 4d707404a..72d35dbd7 100644
--- a/packages/ui/src/i18n/en.ts
+++ b/packages/ui/src/i18n/en.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegating work",
"ui.sessionTurn.status.planning": "Planning next steps",
- "ui.sessionTurn.status.gatheringContext": "Gathering context",
+ "ui.sessionTurn.status.gatheringContext": "Exploring...",
+ "ui.sessionTurn.status.gatheredContext": "Explored",
"ui.sessionTurn.status.searchingCodebase": "Searching the codebase",
"ui.sessionTurn.status.searchingWeb": "Searching the web",
"ui.sessionTurn.status.makingEdits": "Making edits",
diff --git a/packages/ui/src/i18n/es.ts b/packages/ui/src/i18n/es.ts
index 54e786762..7179c6345 100644
--- a/packages/ui/src/i18n/es.ts
+++ b/packages/ui/src/i18n/es.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegando trabajo",
"ui.sessionTurn.status.planning": "Planificando siguientes pasos",
- "ui.sessionTurn.status.gatheringContext": "Recopilando contexto",
+ "ui.sessionTurn.status.gatheringContext": "Explorando...",
+ "ui.sessionTurn.status.gatheredContext": "Explorado",
"ui.sessionTurn.status.searchingCodebase": "Buscando en la base de código",
"ui.sessionTurn.status.searchingWeb": "Buscando en la web",
"ui.sessionTurn.status.makingEdits": "Realizando ediciones",
diff --git a/packages/ui/src/i18n/fr.ts b/packages/ui/src/i18n/fr.ts
index 36551e5f4..6885f4c58 100644
--- a/packages/ui/src/i18n/fr.ts
+++ b/packages/ui/src/i18n/fr.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Délégation du travail",
"ui.sessionTurn.status.planning": "Planification des prochaines étapes",
- "ui.sessionTurn.status.gatheringContext": "Collecte du contexte",
+ "ui.sessionTurn.status.gatheringContext": "Exploration...",
+ "ui.sessionTurn.status.gatheredContext": "Exploré",
"ui.sessionTurn.status.searchingCodebase": "Recherche dans la base de code",
"ui.sessionTurn.status.searchingWeb": "Recherche sur le web",
"ui.sessionTurn.status.makingEdits": "Application des modifications",
diff --git a/packages/ui/src/i18n/ja.ts b/packages/ui/src/i18n/ja.ts
index 039b998d5..7d357c57e 100644
--- a/packages/ui/src/i18n/ja.ts
+++ b/packages/ui/src/i18n/ja.ts
@@ -32,7 +32,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "作業を委任中",
"ui.sessionTurn.status.planning": "次のステップを計画中",
- "ui.sessionTurn.status.gatheringContext": "コンテキストを収集中",
+ "ui.sessionTurn.status.gatheringContext": "探索中...",
+ "ui.sessionTurn.status.gatheredContext": "探索済み",
"ui.sessionTurn.status.searchingCodebase": "コードベースを検索中",
"ui.sessionTurn.status.searchingWeb": "ウェブを検索中",
"ui.sessionTurn.status.makingEdits": "編集を実行中",
diff --git a/packages/ui/src/i18n/ko.ts b/packages/ui/src/i18n/ko.ts
index d77cdfbb2..7bfea2819 100644
--- a/packages/ui/src/i18n/ko.ts
+++ b/packages/ui/src/i18n/ko.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "작업 위임 중",
"ui.sessionTurn.status.planning": "다음 단계 계획 중",
- "ui.sessionTurn.status.gatheringContext": "컨텍스트 수집 중",
+ "ui.sessionTurn.status.gatheringContext": "탐색 중...",
+ "ui.sessionTurn.status.gatheredContext": "탐색됨",
"ui.sessionTurn.status.searchingCodebase": "코드베이스 검색 중",
"ui.sessionTurn.status.searchingWeb": "웹 검색 중",
"ui.sessionTurn.status.makingEdits": "편집 수행 중",
diff --git a/packages/ui/src/i18n/no.ts b/packages/ui/src/i18n/no.ts
index 29b988c96..caea05827 100644
--- a/packages/ui/src/i18n/no.ts
+++ b/packages/ui/src/i18n/no.ts
@@ -36,7 +36,8 @@ export const dict: Record<Keys, string> = {
"ui.sessionTurn.status.delegating": "Delegerer arbeid",
"ui.sessionTurn.status.planning": "Planlegger neste trinn",
- "ui.sessionTurn.status.gatheringContext": "Samler inn kontekst",
+ "ui.sessionTurn.status.gatheringContext": "Utforsker...",
+ "ui.sessionTurn.status.gatheredContext": "Utforsket",
"ui.sessionTurn.status.searchingCodebase": "Søker i kodebasen",
"ui.sessionTurn.status.searchingWeb": "Søker på nettet",
"ui.sessionTurn.status.makingEdits": "Gjør endringer",
diff --git a/packages/ui/src/i18n/pl.ts b/packages/ui/src/i18n/pl.ts
index 2dfcd272e..9d1a860bb 100644
--- a/packages/ui/src/i18n/pl.ts
+++ b/packages/ui/src/i18n/pl.ts
@@ -32,7 +32,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Delegowanie pracy",
"ui.sessionTurn.status.planning": "Planowanie kolejnych kroków",
- "ui.sessionTurn.status.gatheringContext": "Zbieranie kontekstu",
+ "ui.sessionTurn.status.gatheringContext": "Eksplorowanie...",
+ "ui.sessionTurn.status.gatheredContext": "Wyeksplorowano",
"ui.sessionTurn.status.searchingCodebase": "Przeszukiwanie bazy kodu",
"ui.sessionTurn.status.searchingWeb": "Przeszukiwanie sieci",
"ui.sessionTurn.status.makingEdits": "Wprowadzanie zmian",
diff --git a/packages/ui/src/i18n/ru.ts b/packages/ui/src/i18n/ru.ts
index 9494b7605..1c363da2a 100644
--- a/packages/ui/src/i18n/ru.ts
+++ b/packages/ui/src/i18n/ru.ts
@@ -32,7 +32,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "Делегирование работы",
"ui.sessionTurn.status.planning": "Планирование следующих шагов",
- "ui.sessionTurn.status.gatheringContext": "Сбор контекста",
+ "ui.sessionTurn.status.gatheringContext": "Исследование...",
+ "ui.sessionTurn.status.gatheredContext": "Исследовано",
"ui.sessionTurn.status.searchingCodebase": "Поиск в кодовой базе",
"ui.sessionTurn.status.searchingWeb": "Поиск в интернете",
"ui.sessionTurn.status.makingEdits": "Внесение изменений",
diff --git a/packages/ui/src/i18n/th.ts b/packages/ui/src/i18n/th.ts
index 8758d5534..ef8517af2 100644
--- a/packages/ui/src/i18n/th.ts
+++ b/packages/ui/src/i18n/th.ts
@@ -33,7 +33,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "มอบหมายงาน",
"ui.sessionTurn.status.planning": "วางแผนขั้นตอนถัดไป",
- "ui.sessionTurn.status.gatheringContext": "รวบรวมบริบท",
+ "ui.sessionTurn.status.gatheringContext": "กำลังสำรวจ...",
+ "ui.sessionTurn.status.gatheredContext": "สำรวจแล้ว",
"ui.sessionTurn.status.searchingCodebase": "กำลังค้นหาโค้ดเบส",
"ui.sessionTurn.status.searchingWeb": "กำลังค้นหาบนเว็บ",
"ui.sessionTurn.status.makingEdits": "กำลังแก้ไข",
diff --git a/packages/ui/src/i18n/zh.ts b/packages/ui/src/i18n/zh.ts
index fc9c6d68e..2c3bcf1d8 100644
--- a/packages/ui/src/i18n/zh.ts
+++ b/packages/ui/src/i18n/zh.ts
@@ -37,7 +37,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "正在委派工作",
"ui.sessionTurn.status.planning": "正在规划下一步",
- "ui.sessionTurn.status.gatheringContext": "正在收集上下文",
+ "ui.sessionTurn.status.gatheringContext": "正在探索...",
+ "ui.sessionTurn.status.gatheredContext": "已探索",
"ui.sessionTurn.status.searchingCodebase": "正在搜索代码库",
"ui.sessionTurn.status.searchingWeb": "正在搜索网页",
"ui.sessionTurn.status.makingEdits": "正在修改",
diff --git a/packages/ui/src/i18n/zht.ts b/packages/ui/src/i18n/zht.ts
index 248519d4f..00cbbd79d 100644
--- a/packages/ui/src/i18n/zht.ts
+++ b/packages/ui/src/i18n/zht.ts
@@ -37,7 +37,8 @@ export const dict = {
"ui.sessionTurn.status.delegating": "正在委派工作",
"ui.sessionTurn.status.planning": "正在規劃下一步",
- "ui.sessionTurn.status.gatheringContext": "正在收集上下文",
+ "ui.sessionTurn.status.gatheringContext": "正在探索...",
+ "ui.sessionTurn.status.gatheredContext": "已探索",
"ui.sessionTurn.status.searchingCodebase": "正在搜尋程式碼庫",
"ui.sessionTurn.status.searchingWeb": "正在搜尋網頁",
"ui.sessionTurn.status.makingEdits": "正在修改",