diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts
index 5ecdc3bc5..5256d8964 100644
--- a/packages/opencode/src/tool/task.ts
+++ b/packages/opencode/src/tool/task.ts
@@ -8,6 +8,7 @@ import { Identifier } from "../id/id"
import { Agent } from "../agent/agent"
import { SessionLock } from "../session/lock"
import { SessionPrompt } from "../session/prompt"
+import { iife } from "@/util/iife"
export const TaskTool = Tool.define("task", async () => {
const agents = await Agent.list().then((x) => x.filter((a) => a.mode !== "primary"))
@@ -28,12 +29,17 @@ export const TaskTool = Tool.define("task", async () => {
async execute(params, ctx) {
const agent = await Agent.get(params.subagent_type)
if (!agent) throw new Error(`Unknown agent type: ${params.subagent_type} is not a valid agent type`)
- const session = params.session_id
- ? await Session.get(params.session_id)
- : await Session.create({
- parentID: ctx.sessionID,
- title: params.description + ` (@${agent.name} subagent)`,
- })
+ const session = await iife(async () => {
+ if (params.session_id) {
+ const found = await Session.get(params.session_id).catch(() => {})
+ if (found) return found
+ }
+
+ return await Session.create({
+ parentID: ctx.sessionID,
+ title: params.description + ` (@${agent.name} subagent)`,
+ })
+ })
const msg = await MessageV2.get({ sessionID: ctx.sessionID, messageID: ctx.messageID })
if (msg.info.role !== "assistant") throw new Error("Not an assistant message")
@@ -95,12 +101,11 @@ export const TaskTool = Tool.define("task", async () => {
all = await Session.messages({ sessionID: session.id })
all = all.filter((x) => x.info.role === "assistant")
all = all.flatMap((msg) => msg.parts.filter((x: any) => x.type === "tool") as MessageV2.ToolPart[])
- const text = (result.parts.findLast((x: any) => x.type === "text") as any)?.text ?? ""
- const output = text
- ? `${text}
+ const text = result.parts.findLast((x) => x.type === "text")?.text ?? ""
+
+ const output =
+ text + "\n\n" + ["", `Session ID: ${session.id}`, ""].join("\n")
-[task-session:${session.id}]`
- : `[task-session:${session.id}]`
return {
title: params.description,
metadata: {
diff --git a/packages/opencode/src/tool/task.txt b/packages/opencode/src/tool/task.txt
index e6578b6f6..a066757c2 100644
--- a/packages/opencode/src/tool/task.txt
+++ b/packages/opencode/src/tool/task.txt
@@ -18,7 +18,7 @@ When NOT to use the Task tool:
Usage notes:
1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
2. When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
-3. Each agent invocation is stateless. Provide the returned [task-session:] marker as session_id to continue; otherwise include every instruction the agent needs upfront.
+3. Each agent invocation is stateless unless you provide a session_id. Your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
4. The agent's outputs should generally be trusted
5. Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent
6. If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.