Skip to content
28 changes: 27 additions & 1 deletion packages/opencode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Instance } from "../project/instance"
import PROMPT_GENERATE from "./generate.txt"
import PROMPT_COMPACTION from "./prompt/compaction.txt"
import PROMPT_EXPLORE from "./prompt/explore.txt"
import PROMPT_REVIEW from "../command/template/review.txt"
import PROMPT_SUMMARY from "./prompt/summary.txt"
import PROMPT_TITLE from "./prompt/title.txt"
import { PermissionNext } from "@/permission/next"
Expand Down Expand Up @@ -120,6 +121,30 @@ export namespace Agent {
mode: "subagent",
native: true,
},
review: {
name: "review",
description: "Specialized agent for reviewing code changes",
permission: PermissionNext.merge(
defaults,
PermissionNext.fromConfig({
todowrite: "allow",
todoread: "allow",
grep: "allow",
glob: "allow",
bash: "allow",
webfetch: "allow",
websearch: "allow",
codesearch: "allow",
read: "allow",
}),
user,
),
prompt: PROMPT_REVIEW,
options: {},
mode: "subagent",
native: true,
hidden: true,
},
compaction: {
name: "compaction",
mode: "primary",
Expand Down Expand Up @@ -173,14 +198,15 @@ export namespace Agent {
continue
}
let item = result[key]
if (!item)
if (item === undefined) {
item = result[key] = {
name: key,
mode: "all",
permission: PermissionNext.merge(defaults, user),
options: {},
native: false,
}
}
if (value.model) item.model = Provider.parseModel(value.model)
item.prompt = value.prompt ?? item.prompt
item.description = value.description ?? item.description
Expand Down
1 change: 1 addition & 0 deletions packages/opencode/src/command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export namespace Command {
},
[Default.REVIEW]: {
name: Default.REVIEW,
agent: "review",
description: "review changes [commit|branch|pr], defaults to uncommitted",
get template() {
return PROMPT_REVIEW.replace("${path}", Instance.worktree)
Expand Down
5 changes: 3 additions & 2 deletions packages/opencode/src/session/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1530,6 +1530,7 @@ export namespace SessionPrompt {
}

const templateParts = await resolvePromptParts(template)
const agentInfo = await Agent.get(agentName)
const parts =
(agent.mode === "subagent" && command.subtask !== false) || command.subtask === true
? [
Expand All @@ -1538,8 +1539,8 @@ export namespace SessionPrompt {
agent: agent.name,
description: command.description ?? "",
command: input.command,
// TODO: how can we make task tool accept a more complex input?
prompt: templateParts.find((y) => y.type === "text")?.text ?? "",
// If agent already has a prompt defined, don't duplicate it in the user message
prompt: agentInfo?.prompt ? "" : (templateParts.find((y) => y.type === "text")?.text ?? ""),
},
]
: [...templateParts, ...(input.parts ?? [])]
Expand Down