mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
feat(config): add {file:...} syntax support for agent markdown prompts
Enable file content substitution in agent configuration prompts using the
existing `ConfigPaths.substitute` utility. This allows agent markdown files
to reference external file contents via `{file:path}` syntax, with missing
files resolving to empty strings.
Export `substitute` function from ConfigPaths to support agent config
processing.
This commit is contained in:
committed by
Catriel Müller
parent
55abf13cfa
commit
80edeee58f
@@ -13,6 +13,7 @@ import * as ConfigMarkdown from "./markdown"
|
||||
import { ConfigModelID } from "./model-id"
|
||||
import { ConfigParse } from "./parse"
|
||||
import { ConfigPermission } from "./permission"
|
||||
import { ConfigVariable } from "./variable"
|
||||
// kilocode_change start
|
||||
import { KilocodeConfig } from "@/kilocode/config/config"
|
||||
import type { Warning } from "./config"
|
||||
@@ -162,10 +163,18 @@ export async function load(dir: string, warnings?: Warning[]) {
|
||||
// kilocode_change end
|
||||
const name = configEntryNameFromPath(item, patterns)
|
||||
|
||||
const prompt = await ConfigVariable.substitute({
|
||||
text: md.content.trim(),
|
||||
type: "virtual",
|
||||
dir: path.dirname(item),
|
||||
source: item,
|
||||
missing: "empty",
|
||||
})
|
||||
|
||||
const config = {
|
||||
name,
|
||||
...md.data,
|
||||
prompt: md.content.trim(),
|
||||
prompt,
|
||||
}
|
||||
// kilocode_change start - use Effect schema (propertyOrder: original) + non-fatal handleInvalid
|
||||
try {
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import path from "node:path"
|
||||
import fs from "node:fs/promises"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
import { Instance } from "../../src/project/instance"
|
||||
import { Agent } from "../../src/agent/agent"
|
||||
|
||||
describe("agent {file:...} syntax in markdown body", () => {
|
||||
test("loads file content when {file:...} is used in agent body", async () => {
|
||||
await using tmp = await tmpdir({
|
||||
git: true,
|
||||
init: async (dir) => {
|
||||
await Bun.write(path.join(dir, "prompts", "guide.md"), "Guidelines content")
|
||||
|
||||
const agentsDir = path.join(dir, ".kilo", "agents")
|
||||
await fs.mkdir(agentsDir, { recursive: true })
|
||||
await Bun.write(
|
||||
path.join(agentsDir, "test.md"),
|
||||
["---", "description: Test Agent", "---", "Base prompt", "", "{file:../../prompts/guide.md}", ""].join("\n"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const agent = await Agent.get("test")
|
||||
|
||||
expect(agent).toBeDefined()
|
||||
expect(agent?.prompt).toContain("Base prompt")
|
||||
expect(agent?.prompt).toContain("Guidelines content")
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("replaces missing file reference with empty string", async () => {
|
||||
await using tmp = await tmpdir({
|
||||
git: true,
|
||||
init: async (dir) => {
|
||||
const agentsDir = path.join(dir, ".kilo", "agents")
|
||||
await fs.mkdir(agentsDir, { recursive: true })
|
||||
await Bun.write(
|
||||
path.join(agentsDir, "test.md"),
|
||||
["---", "description: Test Agent", "---", "Base prompt", "", "{file:missing.txt}", ""].join("\n"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const agent = await Agent.get("test")
|
||||
|
||||
expect(agent).toBeDefined()
|
||||
expect(agent?.prompt).toContain("Base prompt")
|
||||
expect(agent?.prompt).not.toContain("{file:")
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("resolves multiple file references in same agent", async () => {
|
||||
await using tmp = await tmpdir({
|
||||
git: true,
|
||||
init: async (dir) => {
|
||||
await Bun.write(path.join(dir, "a.md"), "Content A")
|
||||
await Bun.write(path.join(dir, "b.md"), "Content B")
|
||||
|
||||
const agentsDir = path.join(dir, ".kilo", "agents")
|
||||
await fs.mkdir(agentsDir, { recursive: true })
|
||||
await Bun.write(
|
||||
path.join(agentsDir, "test.md"),
|
||||
["---", "description: Test", "---", "Base", "", "{file:../../a.md}", "{file:../../b.md}", ""].join("\n"),
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const agent = await Agent.get("test")
|
||||
|
||||
expect(agent).toBeDefined()
|
||||
expect(agent?.prompt).toContain("Content A")
|
||||
expect(agent?.prompt).toContain("Content B")
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user