diff --git a/packages/coding-agent/src/core/slash-commands.ts b/packages/coding-agent/src/core/slash-commands.ts index fc8ec6bf8d..16ba321b9f 100644 --- a/packages/coding-agent/src/core/slash-commands.ts +++ b/packages/coding-agent/src/core/slash-commands.ts @@ -45,6 +45,7 @@ const CANONICAL_BUILTIN_SLASH_COMMANDS: ReadonlyArray = [ { name: "copy", description: "Copy last agent message to clipboard" }, { name: "name", description: "Set session display name" }, { name: "session", description: "Show session info" }, + { name: "system-prompt", description: "Show the exact system prompt sent to the model" }, { name: "logs", description: "Show where daemon and client logs are saved" }, { name: "traces", diff --git a/packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts b/packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts index 4511699859..11e844c415 100644 --- a/packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts +++ b/packages/coding-agent/src/modes/agent-connection/daemon-agent-connection.ts @@ -366,6 +366,14 @@ export class DaemonAgentConnection implements AgentConnection { return data.text ?? undefined; } + async getSystemPrompt(): Promise { + const data = await this.requestData<{ systemPrompt: string }>({ + type: "get_system_prompt", + activeSessionId: this.activeSessionId, + }); + return data.systemPrompt; + } + async getToolDefinition(name: string): Promise { const data = await this.requestData<{ toolDefinition?: AgentConnectionToolDefinition }>({ type: "get_tool_definition", @@ -832,6 +840,7 @@ function invalidatesCachedSnapshot(commandType: DaemonCommandBody["type"]): bool case "get_session_tree": case "get_user_messages_for_forking": case "get_last_assistant_text": + case "get_system_prompt": case "get_tool_definition": case "export_html": case "export_jsonl": diff --git a/packages/coding-agent/src/modes/agent-connection/deferred-agent-connection.ts b/packages/coding-agent/src/modes/agent-connection/deferred-agent-connection.ts index 0b8363fc17..f237e2abb8 100644 --- a/packages/coding-agent/src/modes/agent-connection/deferred-agent-connection.ts +++ b/packages/coding-agent/src/modes/agent-connection/deferred-agent-connection.ts @@ -325,6 +325,10 @@ export class DeferredAgentConnection implements AgentConnection { return this.real ? this.real.getLastAssistantText() : undefined; } + async getSystemPrompt(): Promise { + return this.real ? this.real.getSystemPrompt() : ""; + } + async getToolDefinition(name: string): Promise { return this.real ? this.real.getToolDefinition(name) : undefined; } diff --git a/packages/coding-agent/src/modes/agent-connection/in-process-agent-connection.ts b/packages/coding-agent/src/modes/agent-connection/in-process-agent-connection.ts index 8c79731872..d3f89996fa 100644 --- a/packages/coding-agent/src/modes/agent-connection/in-process-agent-connection.ts +++ b/packages/coding-agent/src/modes/agent-connection/in-process-agent-connection.ts @@ -184,6 +184,10 @@ export class InProcessAgentConnection implements AgentConnection { return this.session.getLastAssistantText(); } + async getSystemPrompt(): Promise { + return this.session.systemPrompt; + } + async getToolDefinition(name: string): Promise { return createAgentConnectionToolDefinition(this.session.getToolDefinition(name)); } diff --git a/packages/coding-agent/src/modes/agent-connection/types.ts b/packages/coding-agent/src/modes/agent-connection/types.ts index 7b26141254..5c10f7cd73 100644 --- a/packages/coding-agent/src/modes/agent-connection/types.ts +++ b/packages/coding-agent/src/modes/agent-connection/types.ts @@ -554,6 +554,8 @@ export interface AgentConnection { updateHeartbeat(action: AgentHeartbeatUpdateAction): Promise; getUserMessagesForForking(): Promise; getLastAssistantText(): Promise; + /** The system prompt currently in effect for the model (with any per-turn extension changes). */ + getSystemPrompt(): Promise; getToolDefinition(name: string): Promise; setSessionEntryLabel(entryId: string, label: string | undefined): Promise; respondToExtensionUiRequest(requestId: string, response: AgentConnectionExtensionUiResponse): Promise; diff --git a/packages/coding-agent/src/modes/daemon/daemon-mode.ts b/packages/coding-agent/src/modes/daemon/daemon-mode.ts index fd8b00ab31..699afb4688 100644 --- a/packages/coding-agent/src/modes/daemon/daemon-mode.ts +++ b/packages/coding-agent/src/modes/daemon/daemon-mode.ts @@ -150,6 +150,7 @@ const DAEMON_COMMAND_TYPES: ReadonlySet = new Set([ "get_session_tree", "get_user_messages_for_forking", "get_last_assistant_text", + "get_system_prompt", "get_tool_definition", "set_session_entry_label", "extension_ui_response", @@ -1379,6 +1380,13 @@ export class AgentDaemon { }); } + case "get_system_prompt": { + const state = this.getSessionState(command.activeSessionId); + return success(command.id, "get_system_prompt", { + systemPrompt: state.runtime.session.systemPrompt, + }); + } + case "get_tool_definition": { const state = this.getSessionState(command.activeSessionId); return success(command.id, "get_tool_definition", { diff --git a/packages/coding-agent/src/modes/daemon/daemon-protocol.ts b/packages/coding-agent/src/modes/daemon/daemon-protocol.ts index 1b892d2047..f952e38414 100644 --- a/packages/coding-agent/src/modes/daemon/daemon-protocol.ts +++ b/packages/coding-agent/src/modes/daemon/daemon-protocol.ts @@ -238,6 +238,7 @@ export type DaemonCommand = | { id?: string; type: "get_session_tree"; activeSessionId: string } | { id?: string; type: "get_user_messages_for_forking"; activeSessionId: string } | { id?: string; type: "get_last_assistant_text"; activeSessionId: string } + | { id?: string; type: "get_system_prompt"; activeSessionId: string } | { id?: string; type: "get_tool_definition"; activeSessionId: string; name: string } | { id?: string; type: "set_session_entry_label"; activeSessionId: string; entryId: string; label?: string } | { diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index f2719b0bed..2d73264d4a 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -3334,6 +3334,11 @@ export class InteractiveMode { this.editor.setText(""); return; } + if (commandName === "system-prompt" && !commandArgs) { + await this.handleSystemPromptCommand(); + this.editor.setText(""); + return; + } if (commandName === "traces") { await this.handleTracesCommand(canonicalCommandText); this.editor.setText(""); @@ -6715,6 +6720,17 @@ export class InteractiveMode { this.ui.requestRender(); } + private async handleSystemPromptCommand(): Promise { + const prompt = await this.agentConnection.getSystemPrompt(); + const header = `${theme.bold("System Prompt")} ${theme.fg("dim", `(${prompt.length} chars)`)}`; + + this.chatContainer.addChild(new Spacer(1)); + this.chatContainer.addChild(new Text(header, 1, 0)); + this.chatContainer.addChild(new Spacer(1)); + this.chatContainer.addChild(new Text(prompt, 1, 0)); + this.ui.requestRender(); + } + private formatTraceUploadResult(result: AgentTraceUploadResult): string { switch (result.status) { case "uploaded":