diff --git a/packages/opencode/src/kilocode/editor-context.ts b/packages/opencode/src/kilocode/editor-context.ts index 06085e9301f..f5da9bfa33d 100644 --- a/packages/opencode/src/kilocode/editor-context.ts +++ b/packages/opencode/src/kilocode/editor-context.ts @@ -6,36 +6,50 @@ export interface EditorContext { timezone?: string } -function formatDate(timezone?: string): string[] { +/** + * Build static lines from editor context. + * These rarely change during a session and belong in the system prompt + * so they benefit from prompt caching. + */ +export function staticEnvLines(ctx?: EditorContext): string[] { const now = new Date() const lines = [` Today's date: ${now.toDateString()}`] - if (timezone) { + if (ctx?.timezone) { const offset = -now.getTimezoneOffset() const sign = offset >= 0 ? "+" : "-" const hours = Math.floor(Math.abs(offset) / 60) const mins = Math.abs(offset) % 60 - lines.push(` User timezone: ${timezone}, UTC${sign}${hours}:${mins.toString().padStart(2, "0")}`) + lines.push(` User timezone: ${ctx.timezone}, UTC${sign}${hours}:${mins.toString().padStart(2, "0")}`) + } + if (ctx?.shell) { + lines.push(` Default shell: ${ctx.shell}`) } return lines } /** - * Build additional lines from VS Code editor context. - * Returns an array of pre-formatted ` key: value` strings. + * Build a per-message block from editor context. + * These change frequently (user switches files/tabs) and belong in the + * user message so the model always has fresh context. + * Returns undefined when there is nothing dynamic to report. */ -export function editorContextEnvLines(ctx?: EditorContext): string[] { - const lines = formatDate(ctx?.timezone) - if (ctx?.shell) { - lines.push(` Default shell: ${ctx.shell}`) - } +export function environmentDetails(ctx?: EditorContext): string | undefined { + const lines: string[] = [] if (ctx?.activeFile) { - lines.push(` Active file: ${ctx.activeFile}`) + lines.push(`Active file: ${ctx.activeFile}`) } if (ctx?.visibleFiles?.length) { - lines.push(` Visible files: ${ctx.visibleFiles.join(", ")}`) + lines.push(`Visible files:`) + for (const f of ctx.visibleFiles) { + lines.push(` ${f}`) + } } if (ctx?.openTabs?.length) { - lines.push(` Open tabs: ${ctx.openTabs.join(", ")}`) + lines.push(`Open tabs:`) + for (const f of ctx.openTabs) { + lines.push(` ${f}`) + } } - return lines + if (lines.length === 0) return undefined + return ["", ...lines, ""].join("\n") } diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 6779ecc6e12..f90e55ac918 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -47,6 +47,7 @@ import { iife } from "@/util/iife" import { Shell } from "@/shell/shell" import { Truncate } from "@/tool/truncation" import { PlanFollowup } from "@/kilocode/plan-followup" // kilocode_change +import { environmentDetails } from "@/kilocode/editor-context" // kilocode_change // @ts-ignore globalThis.AI_SDK_LOG_WARNINGS = false @@ -1355,6 +1356,20 @@ export namespace SessionPrompt { }), ).then((x) => x.flat().map(assign)) + // kilocode_change start — inject dynamic editor context into user message + const envBlock = environmentDetails(input.editorContext) + if (envBlock) { + parts.push({ + id: Identifier.ascending("part"), + messageID: info.id, + sessionID: input.sessionID, + type: "text", + text: envBlock, + synthetic: true, + }) + } + // kilocode_change end + await Plugin.trigger( "chat.message", { diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index 4c793c014b8..348fd881062 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -13,7 +13,7 @@ import type { Provider } from "@/provider/provider" // kilocode_change start import SOUL from "../kilocode/soul.txt" -import { editorContextEnvLines, type EditorContext } from "../kilocode/editor-context" +import { staticEnvLines, type EditorContext } from "../kilocode/editor-context" // kilocode_change end export namespace SystemPrompt { @@ -67,7 +67,7 @@ export namespace SystemPrompt { ` Working directory: ${Instance.directory}`, ` Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`, ` Platform: ${process.platform}`, - ...editorContextEnvLines(editorContext), // kilocode_change + ...staticEnvLines(editorContext), // kilocode_change ``, ``, ` ${