diff --git a/src/tools/background-task/create-background-output.metadata.test.ts b/src/tools/background-task/create-background-output.metadata.test.ts
new file mode 100644
index 000000000..5111667bb
--- /dev/null
+++ b/src/tools/background-task/create-background-output.metadata.test.ts
@@ -0,0 +1,68 @@
+///
+
+import type { ToolContext } from "@opencode-ai/plugin/tool"
+import { describe, expect, test } from "bun:test"
+import type { BackgroundTask } from "../../features/background-agent"
+import { clearPendingStore, consumeToolMetadata } from "../../features/tool-metadata-store"
+import type { BackgroundOutputClient, BackgroundOutputManager } from "./clients"
+import { createBackgroundOutput } from "./create-background-output"
+
+const projectDir = "/Users/yeongyu/local-workspaces/oh-my-opencode"
+
+type ToolContextWithCallID = ToolContext & {
+ callID: string
+}
+
+describe("createBackgroundOutput metadata", () => {
+ test("omits sessionId metadata when task session is not yet assigned", async () => {
+ // #given
+ clearPendingStore()
+
+ const task: BackgroundTask = {
+ id: "task-1",
+ sessionID: undefined,
+ parentSessionID: "main-1",
+ parentMessageID: "msg-1",
+ description: "background task",
+ prompt: "do work",
+ agent: "test-agent",
+ status: "running",
+ }
+ const manager: BackgroundOutputManager = {
+ getTask: id => (id === task.id ? task : undefined),
+ }
+ const client: BackgroundOutputClient = {
+ session: {
+ messages: async () => ({ data: [] }),
+ },
+ }
+ const tool = createBackgroundOutput(manager, client)
+ const context = {
+ sessionID: "test-session",
+ messageID: "test-message",
+ agent: "test-agent",
+ directory: projectDir,
+ worktree: projectDir,
+ abort: new AbortController().signal,
+ metadata: () => {},
+ ask: async () => {},
+ callID: "call-1",
+ } as ToolContextWithCallID
+
+ // #when
+ await tool.execute({ task_id: task.id }, context)
+
+ // #then
+ expect(consumeToolMetadata("test-session", "call-1")).toEqual({
+ title: "test-agent - background task",
+ metadata: {
+ agent: "test-agent",
+ category: undefined,
+ description: "background task",
+ task_id: "task-1",
+ },
+ })
+
+ clearPendingStore()
+ })
+})
diff --git a/src/tools/background-task/create-background-output.ts b/src/tools/background-task/create-background-output.ts
index 446c0888e..3508052cf 100644
--- a/src/tools/background-task/create-background-output.ts
+++ b/src/tools/background-task/create-background-output.ts
@@ -75,7 +75,7 @@ export function createBackgroundOutput(manager: BackgroundOutputManager, client:
agent: task.agent,
category: task.category,
description: task.description,
- sessionId: task.sessionID ?? "pending",
+ ...(task.sessionID ? { sessionId: task.sessionID } : {}),
} as Record,
}
ctx.metadata?.(meta)
diff --git a/src/tools/background-task/create-background-task.metadata.test.ts b/src/tools/background-task/create-background-task.metadata.test.ts
new file mode 100644
index 000000000..d21e69c09
--- /dev/null
+++ b/src/tools/background-task/create-background-task.metadata.test.ts
@@ -0,0 +1,84 @@
+///
+
+import type { PluginInput } from "@opencode-ai/plugin"
+import type { ToolContext } from "@opencode-ai/plugin/tool"
+import { describe, expect, mock, test } from "bun:test"
+import type { BackgroundManager } from "../../features/background-agent"
+import { clearPendingStore, consumeToolMetadata } from "../../features/tool-metadata-store"
+import { createBackgroundTask } from "./create-background-task"
+
+const projectDir = "/Users/yeongyu/local-workspaces/oh-my-opencode"
+
+type ToolContextWithCallID = ToolContext & {
+ callID: string
+}
+
+describe("createBackgroundTask metadata", () => {
+ test("omits sessionId metadata when session is not yet assigned", async () => {
+ // #given
+ clearPendingStore()
+
+ const manager = {
+ launch: mock(() => Promise.resolve({
+ id: "task-1",
+ sessionID: null,
+ description: "Test task",
+ agent: "test-agent",
+ status: "pending",
+ })),
+ getTask: mock(() => undefined),
+ } as unknown as BackgroundManager
+ const client = {
+ session: {
+ messages: mock(() => Promise.resolve({ data: [] })),
+ },
+ } as unknown as PluginInput["client"]
+
+ let capturedMetadata: { title?: string; metadata?: Record } | undefined
+ const tool = createBackgroundTask(manager, client)
+ const originalDateNow = Date.now
+ let dateNowCallCount = 0
+ Date.now = () => {
+ dateNowCallCount += 1
+ return dateNowCallCount === 1 ? 0 : 30001
+ }
+
+ try {
+ // #when
+ const context: ToolContextWithCallID = {
+ sessionID: "test-session",
+ messageID: "test-message",
+ agent: "test-agent",
+ directory: projectDir,
+ worktree: projectDir,
+ abort: new AbortController().signal,
+ ask: async () => {},
+ callID: "call-1",
+ metadata: input => {
+ capturedMetadata = input
+ },
+ }
+
+ const output = await tool.execute(
+ {
+ description: "Test background task",
+ prompt: "Test prompt",
+ agent: "test-agent",
+ },
+ context
+ )
+
+ // #then
+ expect(output).toContain("Session ID: (not yet assigned)")
+ expect(output).not.toContain('Session ID: pending')
+ expect(capturedMetadata?.metadata).toEqual({})
+ expect(consumeToolMetadata("test-session", "call-1")).toEqual({
+ title: "Test background task",
+ metadata: {},
+ })
+ } finally {
+ Date.now = originalDateNow
+ clearPendingStore()
+ }
+ })
+})
diff --git a/src/tools/background-task/create-background-task.ts b/src/tools/background-task/create-background-task.ts
index 9da0d5c50..8f57ed763 100644
--- a/src/tools/background-task/create-background-task.ts
+++ b/src/tools/background-task/create-background-task.ts
@@ -94,9 +94,11 @@ export function createBackgroundTask(
const bgMeta = {
title: args.description,
- metadata: { sessionId: sessionId ?? "pending" },
+ metadata: {
+ ...(sessionId ? { sessionId } : {}),
+ },
}
- await ctx.metadata?.(bgMeta)
+ ctx.metadata?.(bgMeta)
if (ctx.callID) {
storeToolMetadata(ctx.sessionID, ctx.callID, bgMeta)
@@ -105,7 +107,7 @@ export function createBackgroundTask(
return `Background task launched successfully.
Task ID: ${task.id}
-Session ID: ${sessionId ?? "pending"}
+Session ID: ${sessionId ?? "(not yet assigned)"}
Description: ${task.description}
Agent: ${task.agent}
Status: ${task.status}