fix(delegate-task): strip ZWSP from agent names on background launch path
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -466,4 +466,58 @@ describe("background-agent spawner fallback model promotion", () => {
|
|||||||
})
|
})
|
||||||
expect(promptCalls[0]?.body?.variant).toBe("medium")
|
expect(promptCalls[0]?.body?.variant).toBe("medium")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("strips leading zwsp from prompt body agent before promptAsync", async () => {
|
||||||
|
//#given
|
||||||
|
const promptCalls: Array<{ body?: { agent?: string } }> = []
|
||||||
|
|
||||||
|
const client = {
|
||||||
|
session: {
|
||||||
|
get: async () => ({ data: { directory: "/parent/dir" } }),
|
||||||
|
create: async () => ({ data: { id: "ses_child_clean_agent" } }),
|
||||||
|
promptAsync: async (args?: { body?: { agent?: string } }) => {
|
||||||
|
promptCalls.push(args ?? {})
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const task = createTask({
|
||||||
|
description: "Test task",
|
||||||
|
prompt: "Do work",
|
||||||
|
agent: "\u200Bsisyphus-junior",
|
||||||
|
parentSessionID: "ses_parent",
|
||||||
|
parentMessageID: "msg_parent",
|
||||||
|
})
|
||||||
|
|
||||||
|
const item = {
|
||||||
|
task,
|
||||||
|
input: {
|
||||||
|
description: task.description,
|
||||||
|
prompt: task.prompt,
|
||||||
|
agent: task.agent,
|
||||||
|
parentSessionID: task.parentSessionID,
|
||||||
|
parentMessageID: task.parentMessageID,
|
||||||
|
parentModel: task.parentModel,
|
||||||
|
parentAgent: task.parentAgent,
|
||||||
|
model: task.model,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = {
|
||||||
|
client,
|
||||||
|
directory: "/fallback",
|
||||||
|
concurrencyManager: { release: () => {} },
|
||||||
|
tmuxEnabled: false,
|
||||||
|
onTaskError: () => {},
|
||||||
|
}
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await startTask(item as any, ctx as any)
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(promptCalls).toHaveLength(1)
|
||||||
|
expect(promptCalls[0]?.body?.agent).toBe("sisyphus-junior")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { applySessionPromptParams } from "../../shared/session-prompt-params-hel
|
|||||||
import { subagentSessions } from "../claude-code-session-state"
|
import { subagentSessions } from "../claude-code-session-state"
|
||||||
import { getTaskToastManager } from "../task-toast-manager"
|
import { getTaskToastManager } from "../task-toast-manager"
|
||||||
import { isInsideTmux } from "../../shared/tmux"
|
import { isInsideTmux } from "../../shared/tmux"
|
||||||
|
import { stripAgentListSortPrefix } from "../../shared/agent-display-names"
|
||||||
import type { ConcurrencyManager } from "./concurrency"
|
import type { ConcurrencyManager } from "./concurrency"
|
||||||
|
|
||||||
export const FALLBACK_AGENT = "general"
|
export const FALLBACK_AGENT = "general"
|
||||||
@@ -168,11 +169,12 @@ export async function startTask(
|
|||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
const launchVariant = input.model?.variant
|
const launchVariant = input.model?.variant
|
||||||
|
const normalizedAgent = stripAgentListSortPrefix(input.agent)
|
||||||
|
|
||||||
applySessionPromptParams(sessionID, input.model)
|
applySessionPromptParams(sessionID, input.model)
|
||||||
|
|
||||||
const promptBody = {
|
const promptBody = {
|
||||||
agent: input.agent,
|
agent: normalizedAgent,
|
||||||
...(launchModel ? { model: launchModel } : {}),
|
...(launchModel ? { model: launchModel } : {}),
|
||||||
...(launchVariant ? { variant: launchVariant } : {}),
|
...(launchVariant ? { variant: launchVariant } : {}),
|
||||||
system: input.skillContent,
|
system: input.skillContent,
|
||||||
@@ -180,7 +182,7 @@ export async function startTask(
|
|||||||
task: false,
|
task: false,
|
||||||
call_omo_agent: true,
|
call_omo_agent: true,
|
||||||
question: false,
|
question: false,
|
||||||
...getAgentToolRestrictions(input.agent),
|
...getAgentToolRestrictions(normalizedAgent),
|
||||||
},
|
},
|
||||||
parts: [createInternalAgentTextPart(input.prompt)],
|
parts: [createInternalAgentTextPart(input.prompt)],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,6 +204,50 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () =>
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
testFn("strips leading zwsp from agent name before launching background task", async () => {
|
||||||
|
//#given - display-sorted agent names should be normalized before manager launch
|
||||||
|
const launchCalls: unknown[] = []
|
||||||
|
const manager = {
|
||||||
|
launch: async (input: unknown) => {
|
||||||
|
launchCalls.push(input)
|
||||||
|
return {
|
||||||
|
id: "bg_clean_agent",
|
||||||
|
sessionID: "ses_clean_agent",
|
||||||
|
description: "Clean agent",
|
||||||
|
agent: "sisyphus-junior",
|
||||||
|
status: "running",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getTask: () => ({ sessionID: "ses_clean_agent" }),
|
||||||
|
}
|
||||||
|
|
||||||
|
//#when
|
||||||
|
await executeBackgroundTask(
|
||||||
|
{
|
||||||
|
description: "Clean agent",
|
||||||
|
prompt: "check",
|
||||||
|
run_in_background: true,
|
||||||
|
load_skills: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sessionID: "ses_parent",
|
||||||
|
callID: "call_clean_agent",
|
||||||
|
metadata: async () => {},
|
||||||
|
abort: new AbortController().signal,
|
||||||
|
},
|
||||||
|
{ manager },
|
||||||
|
{ sessionID: "ses_parent", messageID: "msg_clean_agent" },
|
||||||
|
"\u200Bsisyphus-junior",
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
)
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expectFn(launchCalls).toHaveLength(1)
|
||||||
|
expectFn((launchCalls[0] as { agent: string }).agent).toBe("sisyphus-junior")
|
||||||
|
})
|
||||||
|
|
||||||
testFn("keeps launched background task alive when parent aborts before session id resolves", async () => {
|
testFn("keeps launched background task alive when parent aborts before session id resolves", async () => {
|
||||||
//#given - parallel tool execution can abort the parent call after launch succeeds
|
//#given - parallel tool execution can abort the parent call after launch succeeds
|
||||||
const metadataCalls: any[] = []
|
const metadataCalls: any[] = []
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { getSessionTools } from "../../shared/session-tools-store"
|
|||||||
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
|
import { SessionCategoryRegistry } from "../../shared/session-category-registry"
|
||||||
import { QUESTION_DENIED_SESSION_PERMISSION } from "../../shared/question-denied-session-permission"
|
import { QUESTION_DENIED_SESSION_PERMISSION } from "../../shared/question-denied-session-permission"
|
||||||
import { setSessionFallbackChain } from "../../hooks/model-fallback/hook"
|
import { setSessionFallbackChain } from "../../hooks/model-fallback/hook"
|
||||||
|
import { stripAgentListSortPrefix } from "../../shared/agent-display-names"
|
||||||
|
|
||||||
function continueSessionSetup(args: {
|
function continueSessionSetup(args: {
|
||||||
taskID: string
|
taskID: string
|
||||||
@@ -62,11 +63,12 @@ export async function executeBackgroundTask(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const tddEnabled = executorCtx.sisyphusAgentConfig?.tdd
|
const tddEnabled = executorCtx.sisyphusAgentConfig?.tdd
|
||||||
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse, tddEnabled)
|
const normalizedAgent = stripAgentListSortPrefix(agentToUse)
|
||||||
|
const effectivePrompt = buildTaskPrompt(args.prompt, normalizedAgent, tddEnabled)
|
||||||
const task = await manager.launch({
|
const task = await manager.launch({
|
||||||
description: args.description,
|
description: args.description,
|
||||||
prompt: effectivePrompt,
|
prompt: effectivePrompt,
|
||||||
agent: agentToUse,
|
agent: normalizedAgent,
|
||||||
parentSessionID: parentContext.sessionID,
|
parentSessionID: parentContext.sessionID,
|
||||||
parentMessageID: parentContext.messageID,
|
parentMessageID: parentContext.messageID,
|
||||||
parentModel: parentContext.model,
|
parentModel: parentContext.model,
|
||||||
@@ -156,7 +158,7 @@ Do NOT call background_output now. Wait for <system-reminder> notification first
|
|||||||
return formatDetailedError(error, {
|
return formatDetailedError(error, {
|
||||||
operation: "Launch background task",
|
operation: "Launch background task",
|
||||||
args,
|
args,
|
||||||
agent: agentToUse,
|
agent: stripAgentListSortPrefix(agentToUse),
|
||||||
category: args.category,
|
category: args.category,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user