Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/opencode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import PROMPT_COMPACTION from "./prompt/compaction.txt"
import PROMPT_EXPLORE from "./prompt/explore.txt"
import PROMPT_SUMMARY from "./prompt/summary.txt"
import PROMPT_TITLE from "./prompt/title.txt"
import PROMPT_PLAN from "../session/prompt/plan.txt"
import { PermissionNext } from "@/permission/next"
import { mergeDeep, pipe, sortBy, values } from "remeda"

Expand All @@ -35,6 +36,7 @@ export namespace Agent {
prompt: z.string().optional(),
options: z.record(z.string(), z.any()),
steps: z.number().int().positive().optional(),
reminder: z.union([z.string(), z.literal(false)]).optional(),
})
.meta({
ref: "Agent",
Expand Down Expand Up @@ -79,6 +81,8 @@ export namespace Agent {
plan: {
name: "plan",
options: {},
// TODO (for mr dax): update to use the anthropic full fledged one (see plan-reminder-anthropic.txt)
reminder: PROMPT_PLAN,
permission: PermissionNext.merge(
defaults,
PermissionNext.fromConfig({
Expand Down Expand Up @@ -208,6 +212,7 @@ export namespace Agent {
item.steps = value.steps ?? item.steps
item.options = mergeDeep(item.options, value.options ?? {})
item.permission = PermissionNext.merge(item.permission, PermissionNext.fromConfig(value.permission ?? {}))
item.reminder = value.reminder ?? item.reminder
}

// Ensure Truncate.DIR is allowed unless explicitly configured
Expand Down
7 changes: 7 additions & 0 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,12 @@ export namespace Config {
.describe("Maximum number of agentic iterations before forcing text-only response"),
maxSteps: z.number().int().positive().optional().describe("@deprecated Use 'steps' field instead."),
permission: Permission.optional(),
reminder: z
.union([z.string(), z.literal(false)])
.optional()
.describe(
"Custom reminder text injected into user messages for this agent. Set to false to disable the default reminder.",
),
})
.catchall(z.any())
.transform((agent, ctx) => {
Expand All @@ -576,6 +582,7 @@ export namespace Config {
"permission",
"disable",
"tools",
"reminder",
])

// Extract unknown properties into options
Expand Down
11 changes: 7 additions & 4 deletions packages/opencode/src/session/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { Bus } from "../bus"
import { ProviderTransform } from "../provider/transform"
import { SystemPrompt } from "./system"
import { Plugin } from "../plugin"
import PROMPT_PLAN from "../session/prompt/plan.txt"
import BUILD_SWITCH from "../session/prompt/build-switch.txt"
import MAX_STEPS from "../session/prompt/max-steps.txt"
import { defer } from "../util/defer"
Expand Down Expand Up @@ -1173,17 +1172,21 @@ export namespace SessionPrompt {
function insertReminders(input: { messages: MessageV2.WithParts[]; agent: Agent.Info }) {
const userMessage = input.messages.findLast((msg) => msg.info.role === "user")
if (!userMessage) return input.messages
if (input.agent.name === "plan") {

// If agent has a reminder configured (string), inject it
// If reminder is false or undefined, skip injection
if (typeof input.agent.reminder === "string") {
userMessage.parts.push({
id: Identifier.ascending("part"),
messageID: userMessage.info.id,
sessionID: userMessage.info.sessionID,
type: "text",
// TODO (for mr dax): update to use the anthropic full fledged one (see plan-reminder-anthropic.txt)
text: PROMPT_PLAN,
text: input.agent.reminder,
synthetic: true,
})
}

// Notify build agent when switching from plan mode
const wasPlan = input.messages.some((msg) => msg.info.role === "assistant" && msg.info.agent === "plan")
if (wasPlan && input.agent.name === "build") {
userMessage.parts.push({
Expand Down
7 changes: 7 additions & 0 deletions packages/sdk/js/src/v2/gen/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,10 @@ export type AgentConfig = {
*/
maxSteps?: number
permission?: PermissionConfig
/**
* Custom reminder text injected into user messages for this agent. Set to false to disable the default reminder.
*/
reminder?: string | false
[key: string]:
| unknown
| string
Expand All @@ -1367,6 +1371,8 @@ export type AgentConfig = {
| string
| number
| PermissionConfig
| string
| false
| undefined
}

Expand Down Expand Up @@ -2005,6 +2011,7 @@ export type Agent = {
[key: string]: unknown
}
steps?: number
reminder?: string | false
}

export type McpStatusConnected = {
Expand Down