|
|
@@ -11,6 +11,7 @@ import { defaultModeSlug, modes } from "../../../shared/modes"
|
|
|
import "../../../utils/path"
|
|
|
import { addCustomInstructions } from "../sections/custom-instructions"
|
|
|
import * as modesSection from "../sections/modes"
|
|
|
+import { EXPERIMENT_IDS } from "../../../shared/experiments"
|
|
|
|
|
|
// Mock the sections
|
|
|
jest.mock("../sections/modes", () => ({
|
|
|
@@ -121,6 +122,7 @@ const createMockMcpHub = (): McpHub =>
|
|
|
|
|
|
describe("SYSTEM_PROMPT", () => {
|
|
|
let mockMcpHub: McpHub
|
|
|
+ let experiments: Record<string, boolean>
|
|
|
|
|
|
beforeAll(() => {
|
|
|
// Ensure fs mock is properly initialized
|
|
|
@@ -140,6 +142,10 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
"/mock/mcp/path",
|
|
|
]
|
|
|
dirs.forEach((dir) => mockFs._mockDirectories.add(dir))
|
|
|
+ experiments = {
|
|
|
+ [EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
|
|
|
+ [EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
beforeEach(() => {
|
|
|
@@ -164,6 +170,10 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
defaultModeSlug, // mode
|
|
|
undefined, // customModePrompts
|
|
|
undefined, // customModes
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -179,7 +189,11 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
"1280x800", // browserViewportSize
|
|
|
defaultModeSlug, // mode
|
|
|
undefined, // customModePrompts
|
|
|
- undefined, // customModes
|
|
|
+ undefined, // customModes,
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -197,7 +211,11 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // browserViewportSize
|
|
|
defaultModeSlug, // mode
|
|
|
undefined, // customModePrompts
|
|
|
- undefined, // customModes
|
|
|
+ undefined, // customModes,
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -213,7 +231,11 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // browserViewportSize
|
|
|
defaultModeSlug, // mode
|
|
|
undefined, // customModePrompts
|
|
|
- undefined, // customModes
|
|
|
+ undefined, // customModes,
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -229,7 +251,11 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
"900x600", // different viewport size
|
|
|
defaultModeSlug, // mode
|
|
|
undefined, // customModePrompts
|
|
|
- undefined, // customModes
|
|
|
+ undefined, // customModes,
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -249,6 +275,7 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // globalCustomInstructions
|
|
|
undefined, // preferredLanguage
|
|
|
true, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toContain("apply_diff")
|
|
|
@@ -269,6 +296,7 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // globalCustomInstructions
|
|
|
undefined, // preferredLanguage
|
|
|
false, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).not.toContain("apply_diff")
|
|
|
@@ -289,6 +317,7 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // globalCustomInstructions
|
|
|
undefined, // preferredLanguage
|
|
|
undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).not.toContain("apply_diff")
|
|
|
@@ -308,6 +337,8 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // customModes
|
|
|
undefined, // globalCustomInstructions
|
|
|
"Spanish", // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toContain("Language Preference:")
|
|
|
@@ -337,6 +368,9 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
undefined, // customModePrompts
|
|
|
customModes, // customModes
|
|
|
"Global instructions", // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
// Role definition should be at the top
|
|
|
@@ -368,6 +402,10 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
defaultModeSlug,
|
|
|
customModePrompts,
|
|
|
undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
// Role definition from promptComponent should be at the top
|
|
|
@@ -394,18 +432,101 @@ describe("SYSTEM_PROMPT", () => {
|
|
|
defaultModeSlug,
|
|
|
customModePrompts,
|
|
|
undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
// Should use the default mode's role definition
|
|
|
expect(prompt.indexOf(modes[0].roleDefinition)).toBeLessThan(prompt.indexOf("TOOL USE"))
|
|
|
})
|
|
|
|
|
|
+ describe("experimental tools", () => {
|
|
|
+ it("should disable experimental tools by default", async () => {
|
|
|
+ const prompt = await SYSTEM_PROMPT(
|
|
|
+ mockContext,
|
|
|
+ "/test/path",
|
|
|
+ false, // supportsComputerUse
|
|
|
+ undefined, // mcpHub
|
|
|
+ undefined, // diffStrategy
|
|
|
+ undefined, // browserViewportSize
|
|
|
+ defaultModeSlug, // mode
|
|
|
+ undefined, // customModePrompts
|
|
|
+ undefined, // customModes
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments, // experiments - undefined should disable all experimental tools
|
|
|
+ )
|
|
|
+
|
|
|
+ // Verify experimental tools are not included in the prompt
|
|
|
+ expect(prompt).not.toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
|
|
+ expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
|
|
+ })
|
|
|
+
|
|
|
+ it("should enable experimental tools when explicitly enabled", async () => {
|
|
|
+ const experiments = {
|
|
|
+ [EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
|
|
|
+ [EXPERIMENT_IDS.INSERT_BLOCK]: true,
|
|
|
+ }
|
|
|
+
|
|
|
+ const prompt = await SYSTEM_PROMPT(
|
|
|
+ mockContext,
|
|
|
+ "/test/path",
|
|
|
+ false, // supportsComputerUse
|
|
|
+ undefined, // mcpHub
|
|
|
+ undefined, // diffStrategy
|
|
|
+ undefined, // browserViewportSize
|
|
|
+ defaultModeSlug, // mode
|
|
|
+ undefined, // customModePrompts
|
|
|
+ undefined, // customModes
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
+ )
|
|
|
+
|
|
|
+ // Verify experimental tools are included in the prompt when enabled
|
|
|
+ expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
|
|
+ expect(prompt).toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
|
|
+ })
|
|
|
+
|
|
|
+ it("should selectively enable experimental tools", async () => {
|
|
|
+ const experiments = {
|
|
|
+ [EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
|
|
|
+ [EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
|
|
+ }
|
|
|
+
|
|
|
+ const prompt = await SYSTEM_PROMPT(
|
|
|
+ mockContext,
|
|
|
+ "/test/path",
|
|
|
+ false, // supportsComputerUse
|
|
|
+ undefined, // mcpHub
|
|
|
+ undefined, // diffStrategy
|
|
|
+ undefined, // browserViewportSize
|
|
|
+ defaultModeSlug, // mode
|
|
|
+ undefined, // customModePrompts
|
|
|
+ undefined, // customModes
|
|
|
+ undefined, // globalCustomInstructions
|
|
|
+ undefined, // preferredLanguage
|
|
|
+ undefined, // diffEnabled
|
|
|
+ experiments,
|
|
|
+ )
|
|
|
+
|
|
|
+ // Verify only enabled experimental tools are included
|
|
|
+ expect(prompt).toContain(EXPERIMENT_IDS.SEARCH_AND_REPLACE)
|
|
|
+ expect(prompt).not.toContain(EXPERIMENT_IDS.INSERT_BLOCK)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
afterAll(() => {
|
|
|
jest.restoreAllMocks()
|
|
|
})
|
|
|
})
|
|
|
|
|
|
describe("addCustomInstructions", () => {
|
|
|
+ let experiments: Record<string, boolean>
|
|
|
beforeAll(() => {
|
|
|
// Ensure fs mock is properly initialized
|
|
|
const mockFs = jest.requireMock("fs/promises")
|
|
|
@@ -417,6 +538,11 @@ describe("addCustomInstructions", () => {
|
|
|
}
|
|
|
throw new Error(`ENOENT: no such file or directory, mkdir '${path}'`)
|
|
|
})
|
|
|
+
|
|
|
+ experiments = {
|
|
|
+ [EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
|
|
|
+ [EXPERIMENT_IDS.INSERT_BLOCK]: false,
|
|
|
+ }
|
|
|
})
|
|
|
|
|
|
beforeEach(() => {
|
|
|
@@ -434,6 +560,10 @@ describe("addCustomInstructions", () => {
|
|
|
"architect", // mode
|
|
|
undefined, // customModePrompts
|
|
|
undefined, // customModes
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|
|
|
@@ -450,6 +580,10 @@ describe("addCustomInstructions", () => {
|
|
|
"ask", // mode
|
|
|
undefined, // customModePrompts
|
|
|
undefined, // customModes
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ undefined,
|
|
|
+ experiments,
|
|
|
)
|
|
|
|
|
|
expect(prompt).toMatchSnapshot()
|