Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/kilo-vscode/tests/unit/background-agents.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { describe, expect, it } from "bun:test"
import {
backgroundAgents,
backgroundJobAgents,
children,
taskChildren,
fitBackgroundAgents,
showBackgroundAgent,
} from "../../webview-ui/src/components/chat/background-agents"
Expand Down Expand Up @@ -82,13 +82,13 @@ describe("children", () => {
taskPart({ id: "part_3", child: "ses_a" }),
]

expect(children(tools)).toEqual(["ses_a", "ses_b"])
expect(taskChildren(tools)).toEqual(["ses_a", "ses_b"])
})

it("ignores non-task tools and parts without a child session", () => {
const bash = { id: "part_3", type: "tool", tool: "bash", state: { status: "running", input: {} } } as ToolPart

expect(children([bash, taskPart({ id: "part_4", background: true })])).toEqual([])
expect(taskChildren([bash, taskPart({ id: "part_4", background: true })])).toEqual([])
})
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { IconButton } from "@kilocode/kilo-ui/icon-button"
import { createEffect, createMemo, on, type Accessor, type Component } from "solid-js"
import { DataBridge } from "../src/App"
import { ChatView } from "../src/components/chat"
import { children } from "../src/components/chat/background-agents"
import { taskChildren } from "../src/components/chat/background-agents"
import { useLanguage } from "../src/context/language"
import { SessionProvider, useSession, useSessionVisibility } from "../src/context/session"
import { description, label, type Activity } from "../src/utils/session-activity"
Expand Down Expand Up @@ -147,7 +147,7 @@ export const SubagentPanel: Component<Props> = (props) => {
// Colors follow the parent's spawn order so tabs match the parent transcript.
const siblings = createMemo(() => {
const id = session.currentSessionID()
return id ? children(session.getSessionToolParts(id)) : []
return id ? taskChildren(session.getSessionToolParts(id)) : []
})
return (
<AgentAvatarPalette ids={siblings()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { useWorktreeMode } from "../../context/worktree-mode"
import { useServer } from "../../context/server"
import { TranscriptSearchProvider } from "../../context/transcript-search"
import { isPromptBlocked, isSuggesting, isQuestioning } from "./prompt-input-utils"
import { children } from "./background-agents"
import { taskChildren } from "./background-agents"
import { showTabStrip } from "../../utils/local-tabs"
import type { WorktreeReference } from "../../hooks/file-mention-utils"

Expand Down Expand Up @@ -376,7 +376,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
)

// Sibling-aware avatar colors for every subagent spawned by this session.
const siblings = createMemo(() => (id() ? children(session.getSessionToolParts(id()!)) : []))
const siblings = createMemo(() => (id() ? taskChildren(session.getSessionToolParts(id()!)) : []))

return (
<AgentAvatarPalette ids={siblings()}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function meta(part: ToolPart, key: string): unknown {
}

/** Child session IDs of Task tool parts. */
function taskChildren(tools: ToolPart[]): string[] {
export function taskChildren(tools: ToolPart[]): string[] {
const ids: string[] = []
for (const part of tools) {
if (part.tool !== "task") continue
Expand All @@ -78,11 +78,6 @@ function taskChildren(tools: ToolPart[]): string[] {
return ids
}

/** Child session IDs of every Task tool part, in spawn order, without duplicates. */
export function children(tools: ToolPart[]): string[] {
return taskChildren(tools)
}

function working(status: SessionStatusInfo | undefined): boolean {
return status?.type === "busy" || status?.type === "retry"
}
Expand Down
4 changes: 0 additions & 4 deletions packages/ui/src/kilocode/mermaid/markdown-mermaid.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ export default {
id: "kilocode-markdown-mermaid",
}

export const Mermaid = {
render: () => <Markdown text={text} />,
}

export const MermaidError = {
render: () => (
<Markdown
Expand Down
41 changes: 6 additions & 35 deletions packages/ui/src/kilocode/mermaid/markdown-mermaid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,6 @@ export type MermaidLabels = {
close: string
}

const labels: MermaidLabels = {
rendering: "Rendering Mermaid diagram...",
renderError: (message) => `Mermaid render failed: ${message}`,
errorDefault: "Unable to render Mermaid diagram.",
errorEmpty: "Mermaid rendered an empty diagram.",
copied: "Copied",
copy: "Copy",
download: "Download",
copySource: "Copy Mermaid source",
copySvg: "Copy SVG",
copyPng: "Copy PNG",
downloadSvg: "Download SVG",
downloadPng: "Download PNG",
zoom: "Zoom",
zoomIn: "Zoom in",
zoomOut: "Zoom out",
zoomReset: "Reset zoom",
close: "Close",
}

const cache: { promise?: Promise<Mermaid>; id: number; queue: Promise<void> } = {
id: 0,
queue: Promise.resolve(),
Expand Down Expand Up @@ -214,10 +194,6 @@ function sanitize(svg: string) {
return DOMPurify.sanitize(svg, svgConfig)
}

function mergeLabels(input?: Partial<MermaidLabels>) {
return { ...labels, ...input }
}

function message(err: unknown, labels: MermaidLabels) {
if (err instanceof Error) return err.message
if (typeof err === "string") return err
Expand Down Expand Up @@ -412,12 +388,7 @@ async function svg(renderer: Mermaid, source: string, cfg: ReturnType<typeof con
})
}

export async function renderMermaid(
root: HTMLDivElement,
signal: { aborted: boolean },
input?: Partial<MermaidLabels>,
) {
const label = mergeLabels(input)
export async function renderMermaid(root: HTMLDivElement, signal: { aborted: boolean }, labels: MermaidLabels) {
const blocks = Array.from(root.querySelectorAll('pre > code[data-lang="mermaid"]'))
if (blocks.length === 0) return

Expand All @@ -428,7 +399,7 @@ export async function renderMermaid(
if (!(pre instanceof HTMLPreElement)) continue
if (!(wrapper instanceof HTMLElement)) continue
if (wrapper.getAttribute("data-component") !== "markdown-code") continue
fail(wrapper, pre, err, label)
fail(wrapper, pre, err, labels)
}
})
if (!renderer) return
Expand Down Expand Up @@ -470,7 +441,7 @@ export async function renderMermaid(
const el = panel(wrapper)
if (!keep) {
el.setAttribute("data-state", "rendering")
el.textContent = label.rendering
el.textContent = labels.rendering
pre.hidden = false
} else {
pre.hidden = true
Expand All @@ -481,17 +452,17 @@ export async function renderMermaid(
if (signal.aborted || !root.isConnected || !wrapper.isConnected) return

const safe = sanitize(result.svg)
if (!safe) throw new Error(label.errorEmpty)
if (!safe) throw new Error(labels.errorEmpty)

cleanupActions(el)
el.setAttribute("data-state", "rendered")
el.innerHTML = safe
renderActions(el, pre, source, label)
renderActions(el, pre, source, labels)
wrapper.setAttribute("data-mermaid-state", "rendered")
pre.hidden = true
} catch (err) {
if (signal.aborted || !root.isConnected || !wrapper.isConnected) return
fail(wrapper, pre, err, label)
fail(wrapper, pre, err, labels)
}
}
}
Loading