mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix: only include semantic search tool hint when enabled
This commit is contained in:
@@ -13,6 +13,9 @@ const log = Log.create({ service: "kilocode-tool-registry" })
|
||||
type Deps = { agent: Agent.Interface; truncate: Truncate.Interface }
|
||||
|
||||
export namespace KiloToolRegistry {
|
||||
const hint =
|
||||
"- When you are doing an open-ended search where you do not know the exact symbol name, use the `semantic_search` tool first to narrow down the search scope, then follow up with `Grep` and/or `Read`"
|
||||
|
||||
/** Resolve Kilo-specific tool Infos outside any InstanceState, so their Truncate/Agent deps are
|
||||
* satisfied at the outer registry scope instead of leaking into InstanceState's Effect. */
|
||||
export function infos() {
|
||||
@@ -84,4 +87,12 @@ export namespace KiloToolRegistry {
|
||||
...(Flag.KILO_CLIENT === "vscode" && cfg.experimental?.agent_manager_tool === true ? [tools.manager] : []),
|
||||
]
|
||||
}
|
||||
|
||||
export function describe(tools: Tool.Def[], extra: { semantic?: Tool.Def }): Tool.Def[] {
|
||||
if (!extra.semantic) return tools
|
||||
return tools.map((tool) => {
|
||||
if (tool.id !== "glob" && tool.id !== "grep") return tool
|
||||
return { ...tool, description: `${tool.description}\n${hint}` }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
- Returns file paths and line numbers with at least one match sorted by modification time
|
||||
- Use this tool when you need to find files containing specific patterns
|
||||
- If you need to identify/count the number of matches within files, use the Bash tool with `rg` (ripgrep) directly. Do NOT use `grep`.
|
||||
- When you are doing an open-ended search where you do not know the exact symbol name, use the SemanticSearch tool instead
|
||||
- When you are doing a deep search that may require multiple tool invocations, use the Task tool instead
|
||||
|
||||
@@ -226,28 +226,31 @@ export const layer: Layer.Layer<
|
||||
|
||||
return {
|
||||
custom,
|
||||
builtin: [
|
||||
tool.invalid,
|
||||
...(questionEnabled ? [tool.question] : []),
|
||||
tool.bash,
|
||||
tool.read,
|
||||
tool.glob,
|
||||
tool.grep,
|
||||
tool.edit,
|
||||
tool.write,
|
||||
tool.task,
|
||||
tool.fetch,
|
||||
tool.todo,
|
||||
tool.search,
|
||||
tool.skill,
|
||||
tool.patch,
|
||||
// kilocode_change start
|
||||
tool.plan,
|
||||
...(["cli", "vscode"].includes(Flag.KILO_CLIENT) ? [tool.suggest] : []),
|
||||
...KiloToolRegistry.extra(kilo, cfg),
|
||||
// kilocode_change end
|
||||
...(Flag.KILO_EXPERIMENTAL_LSP_TOOL ? [tool.lsp] : []),
|
||||
],
|
||||
builtin: KiloToolRegistry.describe(
|
||||
[
|
||||
tool.invalid,
|
||||
...(questionEnabled ? [tool.question] : []),
|
||||
tool.bash,
|
||||
tool.read,
|
||||
tool.glob,
|
||||
tool.grep,
|
||||
tool.edit,
|
||||
tool.write,
|
||||
tool.task,
|
||||
tool.fetch,
|
||||
tool.todo,
|
||||
tool.search,
|
||||
tool.skill,
|
||||
tool.patch,
|
||||
// kilocode_change start
|
||||
tool.plan,
|
||||
...(["cli", "vscode"].includes(Flag.KILO_CLIENT) ? [tool.suggest] : []),
|
||||
...KiloToolRegistry.extra(kilo, cfg),
|
||||
// kilocode_change end
|
||||
...(Flag.KILO_EXPERIMENTAL_LSP_TOOL ? [tool.lsp] : []),
|
||||
],
|
||||
kilo,
|
||||
), // kilocode_change
|
||||
task: tool.task,
|
||||
read: tool.read,
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { afterEach, describe, expect, spyOn, test } from "bun:test"
|
||||
import { Effect, Layer, Schema } from "effect"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import { Agent } from "../../src/agent/agent"
|
||||
import { KiloIndexing } from "../../src/kilocode/indexing"
|
||||
import { KilocodeBootstrap } from "../../src/kilocode/bootstrap"
|
||||
import { KiloSessions } from "../../src/kilo-sessions/kilo-sessions"
|
||||
import { KiloToolRegistry } from "../../src/kilocode/tool/registry"
|
||||
import { ModelID, ProviderID } from "../../src/provider/schema"
|
||||
import { ToolRegistry } from "../../src/tool/registry"
|
||||
import type * as Tool from "../../src/tool/tool"
|
||||
import { Instance } from "../../src/project/instance"
|
||||
@@ -13,7 +15,11 @@ import * as CrossSpawnSpawner from "@opencode-ai/core/cross-spawn-spawner"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
||||
const node = CrossSpawnSpawner.defaultLayer
|
||||
const it = testEffect(Layer.mergeAll(ToolRegistry.defaultLayer, node))
|
||||
const it = testEffect(Layer.mergeAll(Agent.defaultLayer, ToolRegistry.defaultLayer, node))
|
||||
const ref = {
|
||||
providerID: ProviderID.make("test"),
|
||||
modelID: ModelID.make("test-model"),
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await disposeAllInstances()
|
||||
@@ -120,6 +126,56 @@ describe("kilocode tool registry indexing", () => {
|
||||
),
|
||||
)
|
||||
|
||||
it.live("omits semantic_search hint from glob and grep descriptions when indexing is not ready", () =>
|
||||
provideTmpdirInstance(
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const ready = spyOn(KiloIndexing, "ready").mockReturnValue(false)
|
||||
|
||||
try {
|
||||
const agent = yield* Agent.Service
|
||||
const build = yield* agent.get("build")
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const tools = yield* registry.tools({ ...ref, agent: build })
|
||||
const glob = tools.find((tool) => tool.id === "glob")?.description ?? ""
|
||||
const grep = tools.find((tool) => tool.id === "grep")?.description ?? ""
|
||||
|
||||
expect(glob).not.toContain("semantic_search")
|
||||
expect(grep).not.toContain("semantic_search")
|
||||
} finally {
|
||||
ready.mockRestore()
|
||||
}
|
||||
}),
|
||||
{ git: true },
|
||||
),
|
||||
)
|
||||
|
||||
it.live("includes semantic_search hint in glob and grep descriptions when indexing is ready", () =>
|
||||
provideTmpdirInstance(
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const ready = spyOn(KiloIndexing, "ready").mockReturnValue(true)
|
||||
|
||||
try {
|
||||
const agent = yield* Agent.Service
|
||||
const build = yield* agent.get("build")
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const tools = yield* registry.tools({ ...ref, agent: build })
|
||||
const ids = tools.map((tool) => tool.id)
|
||||
const glob = tools.find((tool) => tool.id === "glob")?.description ?? ""
|
||||
const grep = tools.find((tool) => tool.id === "grep")?.description ?? ""
|
||||
|
||||
expect(ids).toContain("semantic_search")
|
||||
expect(glob).toContain("semantic_search")
|
||||
expect(grep).toContain("semantic_search")
|
||||
} finally {
|
||||
ready.mockRestore()
|
||||
}
|
||||
}),
|
||||
{ git: true },
|
||||
),
|
||||
)
|
||||
|
||||
test("conditionally includes Kilo registry extras", () => {
|
||||
const prev = process.env["KILO_CLIENT"]
|
||||
const def = (id: string): Tool.Def => ({
|
||||
|
||||
Reference in New Issue
Block a user