Luke Parker 2 дней назад
Родитель
Сommit
79fc74afbf

+ 23 - 0
packages/app/e2e/regression/session-timeline-tool-projection.spec.ts

@@ -94,6 +94,29 @@ test("labels V2 read tools from their path input", async ({ page }) => {
   await expect(group.locator('[data-slot="basic-tool-tool-subtitle"]')).toHaveText("a.ts")
 })
 
+test("labels V2 skill tools from IDs and result metadata", async ({ page }) => {
+  const pending = "prt_skill_id"
+  const completed = "prt_skill_name"
+  await setupTimeline(page, {
+    messages: [
+      userMessage(),
+      assistantMessage([
+        toolPart(pending, "skill", "running", { id: "sample-skill" }),
+        toolPart(completed, "skill", "completed", { id: "opencode" }, { metadata: { name: "OpenCode" } }),
+      ]),
+    ],
+  })
+
+  await expect(page.locator(`[data-timeline-part-id="${pending}"] [data-component="text-shimmer"]`)).toHaveAttribute(
+    "aria-label",
+    "sample-skill",
+  )
+  await expect(page.locator(`[data-timeline-part-id="${completed}"] [data-component="text-shimmer"]`)).toHaveAttribute(
+    "aria-label",
+    "OpenCode",
+  )
+})
+
 function questionInput() {
   return { questions: [{ header: "Stability", question: "Keep it stable?", options: [] }] }
 }

+ 8 - 2
packages/session-ui/src/components/message-part.tsx

@@ -479,6 +479,12 @@ function readToolPath(input: Record<string, unknown>) {
   if (typeof input.filePath === "string") return input.filePath
 }
 
+function skillToolName(input: Record<string, unknown>, metadata?: Record<string, unknown>) {
+  if (typeof metadata?.name === "string") return metadata.name
+  if (typeof input.id === "string") return input.id
+  if (typeof input.name === "string") return input.name
+}
+
 export function getToolInfo(
   tool: string,
   input: any = {},
@@ -575,7 +581,7 @@ export function getToolInfo(
     case "skill":
       return {
         icon: "brain",
-        title: input.name || i18n.t("ui.tool.skill"),
+        title: skillToolName(input, metadata) || i18n.t("ui.tool.skill"),
       }
     default:
       return {
@@ -2631,7 +2637,7 @@ ToolRegistry.register({
   name: "skill",
   render(props) {
     const i18n = useI18n()
-    const title = createMemo(() => props.input.name || i18n.t("ui.tool.skill"))
+    const title = createMemo(() => skillToolName(props.input, props.metadata) || i18n.t("ui.tool.skill"))
     const running = createMemo(() => props.status === "pending" || props.status === "running")
 
     const titleContent = () => <TextShimmer text={title()} active={running()} />