Files
kilocode/packages/opencode/test/kilocode/system-prompt.test.ts
T

151 lines
6.0 KiB
TypeScript

import { describe, expect, test } from "bun:test"
import { SystemPrompt } from "../../src/session/system"
import { environmentDetails } from "../../src/kilocode/editor-context"
import { ProviderTest } from "../fake/provider"
import PROMPT_ANTHROPIC from "../../src/session/prompt/anthropic.txt"
import PROMPT_DEFAULT from "../../src/session/prompt/default.txt"
import PROMPT_BEAST from "../../src/session/prompt/beast.txt"
import PROMPT_CODEX from "../../src/session/prompt/codex.txt"
import PROMPT_GEMINI from "../../src/session/prompt/gemini.txt"
import PROMPT_GPT from "../../src/session/prompt/gpt.txt"
import PROMPT_GPT55 from "../../src/session/prompt/kilocode-gpt-5.5.txt"
import PROMPT_LING from "../../src/session/prompt/ling.txt"
import PROMPT_TRINITY from "../../src/session/prompt/trinity.txt"
describe("SystemPrompt.provider", () => {
describe("model.prompt override", () => {
test("anthropic prompt is selected when model.prompt is 'anthropic'", () => {
const model = ProviderTest.model({ prompt: "anthropic" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_ANTHROPIC])
})
test("default prompt is selected when model.prompt is 'anthropic_without_todo'", () => {
const model = ProviderTest.model({ prompt: "anthropic_without_todo" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_DEFAULT])
})
test("beast prompt is selected when model.prompt is 'beast'", () => {
const model = ProviderTest.model({ prompt: "beast" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_BEAST])
})
test("codex prompt is selected when model.prompt is 'codex'", () => {
const model = ProviderTest.model({ prompt: "codex" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_CODEX])
})
test("GPT-5.5 prompt is selected from prompt metadata", () => {
const model = ProviderTest.model({
prompt: "gpt55",
api: { id: "provider-specific-model", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_GPT55])
})
test("gemini prompt is selected when model.prompt is 'gemini'", () => {
const model = ProviderTest.model({ prompt: "gemini" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_GEMINI])
expect(PROMPT_GEMINI).toContain("filePath argument")
expect(PROMPT_GEMINI).not.toContain("file_path argument")
})
test("trinity prompt is selected when model.prompt is 'trinity'", () => {
const model = ProviderTest.model({ prompt: "trinity" })
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_TRINITY])
})
test("model.prompt takes precedence over model.api.id heuristic", () => {
// A model whose api.id contains "claude" (which would match anthropic via heuristic)
// but has prompt set to "beast" — prompt should win
const model = ProviderTest.model({
prompt: "beast",
api: { id: "anthropic/claude-4-opus", url: "https://example.com", npm: "@ai-sdk/anthropic" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_BEAST])
})
test("model.api.id heuristic is used when model.prompt is undefined", () => {
const model = ProviderTest.model({
prompt: undefined,
api: { id: "anthropic/claude-4-opus", url: "https://example.com", npm: "@ai-sdk/anthropic" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_ANTHROPIC])
})
test("Ling fallback runs after upstream model id heuristics", () => {
const model = ProviderTest.model({
prompt: undefined,
api: { id: "gpt-5-ling", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_GPT])
})
test("Ling fallback is selected after upstream heuristics miss", () => {
const model = ProviderTest.model({
prompt: undefined,
api: { id: "ling-2", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_LING])
})
test("GPT-5.5 model ids are not prompt-special without metadata", () => {
const model = ProviderTest.model({
prompt: undefined,
api: { id: "gpt-5.5", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_GPT])
})
test("codex prompt metadata still wins for GPT-5.5 model ids", () => {
const model = ProviderTest.model({
prompt: "codex",
api: { id: "gpt-5.5", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_CODEX])
})
test("older Codex model ids keep the Codex prompt", () => {
const model = ProviderTest.model({
prompt: undefined,
api: { id: "gpt-5.1-codex", url: "https://example.com", npm: "@ai-sdk/openai" },
})
const result = SystemPrompt.provider(model)
expect(result).toEqual([PROMPT_CODEX])
})
})
})
describe("environmentDetails", () => {
test("includes cwd and worktree in dynamic context", () => {
const result = environmentDetails({
directory: "/repo/.kilo/worktrees/feature",
worktree: "/repo/.kilo/worktrees/feature",
activeFile: "src/app.ts",
})
expect(result).toContain("Working directory: /repo/.kilo/worktrees/feature")
expect(result).toContain("Workspace root folder: /repo/.kilo/worktrees/feature")
expect(result).toContain("Active file: src/app.ts")
})
test("formats the supplied message time", () => {
const result = environmentDetails({}, new Date("2026-08-24T12:34:56.123Z"))
expect(result).toContain("Message time: 2026-08-24T12:34:56Z")
})
})