Bladeren bron

fix(app): don't rely on metadata.summary in task tool render (#12497)

Adam 2 maanden geleden
bovenliggende
commit
9497cfdf45
2 gewijzigde bestanden met toevoegingen van 18 en 48 verwijderingen
  1. 0 38
      packages/opencode/src/tool/task.ts
  2. 18 10
      packages/ui/src/components/message-part.tsx

+ 0 - 38
packages/opencode/src/tool/task.ts

@@ -2,7 +2,6 @@ import { Tool } from "./tool"
 import DESCRIPTION from "./task.txt"
 import z from "zod"
 import { Session } from "../session"
-import { Bus } from "../bus"
 import { MessageV2 } from "../session/message-v2"
 import { Identifier } from "../id/id"
 import { Agent } from "../agent/agent"
@@ -118,28 +117,6 @@ export const TaskTool = Tool.define("task", async (ctx) => {
       })
 
       const messageID = Identifier.ascending("message")
-      const parts: Record<string, { id: string; tool: string; state: { status: string; title?: string } }> = {}
-      const unsub = Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
-        if (evt.properties.part.sessionID !== session.id) return
-        if (evt.properties.part.messageID === messageID) return
-        if (evt.properties.part.type !== "tool") return
-        const part = evt.properties.part
-        parts[part.id] = {
-          id: part.id,
-          tool: part.tool,
-          state: {
-            status: part.state.status,
-            title: part.state.status === "completed" ? part.state.title : undefined,
-          },
-        }
-        ctx.metadata({
-          title: params.description,
-          metadata: {
-            sessionId: session.id,
-            model,
-          },
-        })
-      })
 
       function cancel() {
         SessionPrompt.cancel(session.id)
@@ -163,22 +140,8 @@ export const TaskTool = Tool.define("task", async (ctx) => {
           ...Object.fromEntries((config.experimental?.primary_tools ?? []).map((t) => [t, false])),
         },
         parts: promptParts,
-      }).finally(() => {
-        unsub()
       })
 
-      const messages = await Session.messages({ sessionID: session.id })
-      const summary = messages
-        .filter((x) => x.info.role === "assistant")
-        .flatMap((msg) => msg.parts.filter((x: any) => x.type === "tool") as MessageV2.ToolPart[])
-        .map((part) => ({
-          id: part.id,
-          tool: part.tool,
-          state: {
-            status: part.state.status,
-            title: part.state.status === "completed" ? part.state.title : undefined,
-          },
-        }))
       const text = result.parts.findLast((x) => x.type === "text")?.text ?? ""
 
       const output = [
@@ -192,7 +155,6 @@ export const TaskTool = Tool.define("task", async (ctx) => {
       return {
         title: params.description,
         metadata: {
-          summary,
           sessionId: session.id,
           model,
         },

+ 18 - 10
packages/ui/src/components/message-part.tsx

@@ -876,16 +876,18 @@ ToolRegistry.register({
   render(props) {
     const data = useData()
     const i18n = useI18n()
-    const summary = () =>
-      (props.metadata.summary ?? []) as { id: string; tool: string; state: { status: string; title?: string } }[]
+    const childSessionId = () => props.metadata.sessionId as string | undefined
+    const childToolParts = createMemo(() => {
+      const sessionId = childSessionId()
+      if (!sessionId) return []
+      return getSessionToolParts(data.store, sessionId)
+    })
 
     const autoScroll = createAutoScroll({
       working: () => true,
       overflowAnchor: "auto",
     })
 
-    const childSessionId = () => props.metadata.sessionId as string | undefined
-
     const childPermission = createMemo(() => {
       const sessionId = childSessionId()
       if (!sessionId) return undefined
@@ -1006,15 +1008,21 @@ ToolRegistry.register({
                 data-scrollable
               >
                 <div ref={autoScroll.contentRef} data-component="task-tools">
-                  <For each={summary()}>
+                  <For each={childToolParts()}>
                     {(item) => {
-                      const info = getToolInfo(item.tool)
+                      const info = createMemo(() => getToolInfo(item.tool, item.state.input))
+                      const subtitle = createMemo(() => {
+                        if (info().subtitle) return info().subtitle
+                        if (item.state.status === "completed" || item.state.status === "running") {
+                          return item.state.title
+                        }
+                      })
                       return (
                         <div data-slot="task-tool-item">
-                          <Icon name={info.icon} size="small" />
-                          <span data-slot="task-tool-title">{info.title}</span>
-                          <Show when={item.state.title}>
-                            <span data-slot="task-tool-subtitle">{item.state.title}</span>
+                          <Icon name={info().icon} size="small" />
+                          <span data-slot="task-tool-title">{info().title}</span>
+                          <Show when={subtitle()}>
+                            <span data-slot="task-tool-subtitle">{subtitle()}</span>
                           </Show>
                         </div>
                       )