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: 6 additions & 0 deletions .changeset/swe-pruner-experimental.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@kilocode/cli": minor
"@kilocode/sdk": minor
---

Add experimental SWE-Pruner support (disabled by default). When enabled via `experimental.swe_pruner` or the Experimental settings tab in VS Code, the read and grep tools accept an optional `context_focus_question` parameter; when the agent provides it, large tool outputs are pruned by a small model down to the lines relevant to that question, with omitted sections marked inline and a `SWE-Pruner · kept/total` indicator on the tool row. The skimming model can be overridden via `experimental.swe_pruner_model` (defaults to the configured small model). Any pruning failure falls back to the full output.
2 changes: 2 additions & 0 deletions packages/kilo-docs/source-links.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
<!-- packages/opencode/src/cli/cmd/tui/config/tui-migrate.ts -->
- <https://app.kilo.ai/usage>
<!-- packages/opencode/src/kilocode/components/dialog-kilo-profile.tsx -->
- <https://arxiv.org/abs/2601.16746>
<!-- packages/opencode/src/kilocode/swe-pruner.ts -->
- <https://auth.x.ai>
<!-- packages/opencode/src/plugin/xai.ts -->
- <https://auth.x.ai/oauth2/authorize>
Expand Down
62 changes: 39 additions & 23 deletions packages/kilo-ui/src/components/message-part.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,14 @@ function ToolText(props: { text: string; delay?: number; animate?: boolean }) {
)
}

function swePruned(metadata: Record<string, unknown>) {
const value = metadata["swePruner"]
if (typeof value !== "object" || value === null) return undefined
const info = value as { kept?: unknown; total?: unknown }
if (typeof info.kept !== "number" || typeof info.total !== "number") return undefined
return { kept: info.kept, total: info.total }
}

function ToolLoadedFile(props: { text: string; animate?: boolean; onClick?: () => void }) {
let ref: HTMLDivElement | undefined
useToolFade(() => ref, { delay: 0.02, wipe: true, animate: props.animate })
Expand Down Expand Up @@ -1758,10 +1766,9 @@ ToolRegistry.register({
if (!value || !Array.isArray(value)) return []
return value.filter((p): p is string => typeof p === "string")
})
const pruned = createMemo(() => swePruned(props.metadata))
const pending = createMemo(() => busy(props.status))
const images = createMemo(() =>
(props.attachments ?? []).filter((f) => f.mime.startsWith("image/") && f.url),
)
const images = createMemo(() => (props.attachments ?? []).filter((f) => f.mime.startsWith("image/") && f.url))
const preview = (url: string, alt?: string) => dialog.show(() => <ImagePreview src={url} alt={alt} />)
return (
<>
Expand Down Expand Up @@ -1808,6 +1815,9 @@ ToolRegistry.register({
</For>
</div>
</Show>
<Show when={pruned()}>
{(info) => <ToolLoadedFile text={i18n.t("ui.tool.swePruned", info())} animate={props.reveal} />}
</Show>
</>
)
},
Expand Down Expand Up @@ -1881,29 +1891,35 @@ ToolRegistry.register({
const args: string[] = []
if (props.input.pattern) args.push("pattern=" + props.input.pattern)
if (props.input.include) args.push("include=" + props.input.include)
const pruned = createMemo(() => swePruned(props.metadata))
const pending = createMemo(() => busy(props.status))
return (
<BasicTool
{...props}
icon="magnifying-glass-menu"
trigger={
<ToolTriggerRow
title={i18n.t("ui.tool.grep")}
pending={pending()}
subtitle={getDirectory(props.input.path)}
args={args}
animate={props.reveal}
/>
}
>
<Show when={props.output}>
{(output) => (
<div data-component="tool-output" data-variant="preview" data-scrollable>
<Markdown text={output()} />
</div>
)}
<>
<BasicTool
{...props}
icon="magnifying-glass-menu"
trigger={
<ToolTriggerRow
title={i18n.t("ui.tool.grep")}
pending={pending()}
subtitle={getDirectory(props.input.path)}
args={args}
animate={props.reveal}
/>
}
>
<Show when={props.output}>
{(output) => (
<div data-component="tool-output" data-variant="preview" data-scrollable>
<Markdown text={output()} />
</div>
)}
</Show>
</BasicTool>
<Show when={pruned()}>
{(info) => <ToolLoadedFile text={i18n.t("ui.tool.swePruned", info())} animate={props.reveal} />}
</Show>
</BasicTool>
</>
)
},
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { useConfig } from "../../context/config"
import { useLanguage } from "../../context/language"
import { useVSCode } from "../../context/vscode"
import type { ExtensionMessage } from "../../types/messages"
import { parseModelString } from "../../../../src/shared/provider-model"
import { ModelSelectorBase } from "../shared/ModelSelector"
import SettingsRow from "./SettingsRow"

interface ShareOption {
Expand Down Expand Up @@ -180,6 +182,38 @@ const ExperimentalTab: Component = () => {
</Switch>
</SettingsRow>

<SettingsRow
title={language.t("settings.experimental.swePruner.title")}
description={language.t("settings.experimental.swePruner.description")}
>
<Switch
checked={experimental().swe_pruner ?? false}
onChange={(checked) => updateExperimental("swe_pruner", checked)}
hideLabel
>
{language.t("settings.experimental.swePruner.title")}
</Switch>
</SettingsRow>

<Show when={experimental().swe_pruner}>
<SettingsRow
title={language.t("settings.experimental.swePrunerModel.title")}
description={language.t("settings.experimental.swePrunerModel.description")}
>
<ModelSelectorBase
value={parseModelString(experimental().swe_pruner_model ?? undefined)}
onSelect={(providerID, modelID) =>
updateExperimental("swe_pruner_model", providerID && modelID ? `${providerID}/${modelID}` : null)
}
placement="bottom-start"
allowClear
clearLabel={language.t("settings.providers.notSet")}
label={language.t("settings.experimental.swePrunerModel.title")}
description={language.t("settings.experimental.swePrunerModel.description")}
/>
</SettingsRow>
</Show>

{/* MCP timeout */}
<SettingsRow
title={language.t("settings.experimental.mcpTimeout.title")}
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ar.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/br.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/bs.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/da.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,12 @@ export const dict = {
"settings.sandboxing.writablePaths.title": "Zusätzliche schreibbare Pfade",
"settings.sandboxing.writablePaths.description":
"Zusätzliche Dateisystempfade, in die die Sandbox Schreibvorgänge erlaubt (z. B. /tmp, /var/log). Diese werden mit den Standard-Schreibpfaden zusammengeführt, wenn die Sandbox aktiv ist.",
"settings.experimental.swePruner.title": "SWE-Pruner",
"settings.experimental.swePruner.description":
"SWE-Pruner aktivieren: aufgabenbezogenes Kürzen großer Lese- und Suchausgaben, gesteuert durch eine Fokusfrage des Agenten",
"settings.experimental.swePrunerModel.title": "SWE-Pruner-Modell",
"settings.experimental.swePrunerModel.description":
"Modell zum Kürzen von Tool-Ausgaben; standardmäßig das konfigurierte Small Model",
"settings.experimental.mcpTimeout.title": "MCP-Zeitlimit (ms)",
"settings.experimental.mcpTimeout.description": "Zeitlimit für MCP-Server-Anfragen in Millisekunden",
"settings.experimental.remote.title": "Remote-Steuerung",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,12 @@ export const dict = {
"settings.sandboxing.writablePaths.title": "Additional Writable Paths",
"settings.sandboxing.writablePaths.description":
"Extra filesystem paths the sandbox allows writes to (e.g. /tmp, /var/log). These are merged with the default writable paths when the sandbox is active.",
"settings.experimental.swePruner.title": "SWE-Pruner",
"settings.experimental.swePruner.description":
"Enable SWE-Pruner: task-aware pruning of large read and search tool outputs, guided by a focus question from the agent",
"settings.experimental.swePrunerModel.title": "SWE-Pruner Model",
"settings.experimental.swePrunerModel.description":
"Model used to skim tool outputs; defaults to the configured small model",
"settings.experimental.mcpTimeout.title": "MCP Timeout (ms)",
"settings.experimental.mcpTimeout.description": "Timeout for MCP server requests in milliseconds",
"settings.experimental.remote.title": "Remote Control",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/es.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/fr.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/it.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ja.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ko.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/nl.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading