Merge pull request #3167 from code-yeongyu/fix/agent-header-validation
fix(agent-names): use HTTP-header-safe display names and config keys for API calls
This commit is contained in:
@@ -89,7 +89,7 @@ describe("message.part.delta handling", () => {
|
||||
//#given
|
||||
const ctx = createMockContext("ses_main")
|
||||
const state = createEventState()
|
||||
state.agentColorsByName["Sisyphus (Ultraworker)"] = "#00CED1"
|
||||
state.agentColorsByName["Sisyphus - Ultraworker"] = "#00CED1"
|
||||
const stdoutSpy = spyOn(process.stdout, "write").mockImplementation(() => true)
|
||||
const payload: EventPayload = {
|
||||
type: "message.updated",
|
||||
@@ -97,7 +97,7 @@ describe("message.part.delta handling", () => {
|
||||
info: {
|
||||
sessionID: "ses_main",
|
||||
role: "assistant",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
modelID: "claude-opus-4-6",
|
||||
variant: "max",
|
||||
},
|
||||
@@ -115,7 +115,7 @@ describe("message.part.delta handling", () => {
|
||||
expect(rendered).toContain("\u001b[38;2;0;206;209m")
|
||||
expect(rendered).toContain("claude-opus-4-6 (max)")
|
||||
expect(rendered).toContain("└─")
|
||||
expect(rendered).toContain("Sisyphus (Ultraworker)")
|
||||
expect(rendered).toContain("Sisyphus - Ultraworker")
|
||||
stdoutSpy.mockRestore()
|
||||
})
|
||||
|
||||
@@ -128,7 +128,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -187,7 +187,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -242,7 +242,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -309,7 +309,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -353,7 +353,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6", variant: "max" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6", variant: "max" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -388,7 +388,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_user", sessionID: "ses_main", role: "user", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_user", sessionID: "ses_main", role: "user", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -410,7 +410,7 @@ describe("message.part.delta handling", () => {
|
||||
{
|
||||
type: "message.updated",
|
||||
properties: {
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus (Ultraworker)", modelID: "claude-opus-4-6" },
|
||||
info: { id: "msg_assistant", sessionID: "ses_main", role: "assistant", agent: "Sisyphus - Ultraworker", modelID: "claude-opus-4-6" },
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ describe("resolveRunAgent", () => {
|
||||
)
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Hephaestus (Deep Agent)")
|
||||
expect(agent).toBe("Hephaestus - Deep Agent")
|
||||
})
|
||||
|
||||
it("uses env agent over config", () => {
|
||||
@@ -43,7 +43,7 @@ describe("resolveRunAgent", () => {
|
||||
const agent = resolveRunAgent({ message: "test" }, config, env)
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Atlas (Plan Executor)")
|
||||
expect(agent).toBe("Atlas - Plan Executor")
|
||||
})
|
||||
|
||||
it("uses config agent over default", () => {
|
||||
@@ -54,7 +54,7 @@ describe("resolveRunAgent", () => {
|
||||
const agent = resolveRunAgent({ message: "test" }, config, {})
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Prometheus (Plan Builder)")
|
||||
expect(agent).toBe("Prometheus - Plan Builder")
|
||||
})
|
||||
|
||||
it("falls back to sisyphus when none set", () => {
|
||||
@@ -65,7 +65,7 @@ describe("resolveRunAgent", () => {
|
||||
const agent = resolveRunAgent({ message: "test" }, config, {})
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Sisyphus (Ultraworker)")
|
||||
expect(agent).toBe("Sisyphus - Ultraworker")
|
||||
})
|
||||
|
||||
it("skips disabled sisyphus for next available core agent", () => {
|
||||
@@ -76,18 +76,18 @@ describe("resolveRunAgent", () => {
|
||||
const agent = resolveRunAgent({ message: "test" }, config, {})
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Hephaestus (Deep Agent)")
|
||||
expect(agent).toBe("Hephaestus - Deep Agent")
|
||||
})
|
||||
|
||||
it("maps display-name style default_run_agent values to canonical display names", () => {
|
||||
// given
|
||||
const config = createConfig({ default_run_agent: "Sisyphus (Ultraworker)" })
|
||||
const config = createConfig({ default_run_agent: "Sisyphus - Ultraworker" })
|
||||
|
||||
// when
|
||||
const agent = resolveRunAgent({ message: "test" }, config, {})
|
||||
|
||||
// then
|
||||
expect(agent).toBe("Sisyphus (Ultraworker)")
|
||||
expect(agent).toBe("Sisyphus - Ultraworker")
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ describe("claude-code-session-state", () => {
|
||||
test("should strip zero-width ordering prefixes before storing agent for session", () => {
|
||||
// given
|
||||
const sessionID = "test-session-prefixed"
|
||||
const agent = "\u200B\u200B\u200BPrometheus (Plan Builder)"
|
||||
const agent = "\u200B\u200B\u200BPrometheus - Plan Builder"
|
||||
|
||||
// when
|
||||
setSessionAgent(sessionID, agent)
|
||||
|
||||
// then
|
||||
expect(getSessionAgent(sessionID)).toBe("Prometheus (Plan Builder)")
|
||||
expect(getSessionAgent(sessionID)).toBe("Prometheus - Plan Builder")
|
||||
})
|
||||
|
||||
test("should NOT overwrite existing agent (first-write wins)", () => {
|
||||
@@ -88,10 +88,10 @@ describe("claude-code-session-state", () => {
|
||||
setSessionAgent(sessionID, "sisyphus")
|
||||
|
||||
// when
|
||||
updateSessionAgent(sessionID, "\u200B\u200BHephaestus (Deep Agent)")
|
||||
updateSessionAgent(sessionID, "\u200B\u200BHephaestus - Deep Agent")
|
||||
|
||||
// then
|
||||
expect(getSessionAgent(sessionID)).toBe("Hephaestus (Deep Agent)")
|
||||
expect(getSessionAgent(sessionID)).toBe("Hephaestus - Deep Agent")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -133,21 +133,21 @@ describe("claude-code-session-state", () => {
|
||||
describe("agent registration", () => {
|
||||
test("should register config-key lookup when given a display name", () => {
|
||||
// given
|
||||
registerAgentName("Atlas (Plan Executor)")
|
||||
registerAgentName("Atlas - Plan Executor")
|
||||
|
||||
// when / then
|
||||
expect(isAgentRegistered("atlas")).toBe(true)
|
||||
expect(isAgentRegistered("Atlas (Plan Executor)")).toBe(true)
|
||||
expect(isAgentRegistered("Atlas - Plan Executor")).toBe(true)
|
||||
})
|
||||
|
||||
describe("#given atlas display name with zero-width prefix", () => {
|
||||
describe("#when checking registration without the zero-width prefix", () => {
|
||||
test("#then it treats the display name as registered", () => {
|
||||
// given
|
||||
registerAgentName("\u200BAtlas (Plan Executor)")
|
||||
registerAgentName("\u200BAtlas - Plan Executor")
|
||||
|
||||
// when
|
||||
const isRegistered = isAgentRegistered("Atlas (Plan Executor)")
|
||||
const isRegistered = isAgentRegistered("Atlas - Plan Executor")
|
||||
|
||||
// then
|
||||
expect(isRegistered).toBe(true)
|
||||
|
||||
@@ -1817,10 +1817,10 @@ session_id: ses_untrusted_999
|
||||
started_at: "2026-01-02T10:00:00Z",
|
||||
session_ids: [MAIN_SESSION_ID],
|
||||
plan_name: "test-plan",
|
||||
agent: "Atlas (Plan Executor)",
|
||||
agent: "Atlas - Plan Executor",
|
||||
}
|
||||
writeBoulderState(TEST_DIR, state)
|
||||
registerAgentName("Atlas (Plan Executor)")
|
||||
registerAgentName("Atlas - Plan Executor")
|
||||
|
||||
const mockInput = createMockPluginInput()
|
||||
const hook = createAtlasHook(mockInput)
|
||||
@@ -1836,7 +1836,7 @@ session_id: ses_untrusted_999
|
||||
// then
|
||||
expect(mockInput._promptMock).toHaveBeenCalled()
|
||||
const callArgs = mockInput._promptMock.mock.calls[0][0]
|
||||
expect(callArgs.body.agent).toBe("Atlas (Plan Executor)")
|
||||
expect(callArgs.body.agent).toBe("Atlas - Plan Executor")
|
||||
expect(callArgs.body.agent).not.toBe("atlas")
|
||||
})
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ describe("model fallback hook", () => {
|
||||
|
||||
const set = setPendingModelFallback(
|
||||
"ses_model_fallback_main",
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"anthropic",
|
||||
"claude-opus-4-6-thinking",
|
||||
)
|
||||
@@ -132,7 +132,7 @@ describe("model fallback hook", () => {
|
||||
const sessionID = "ses_model_fallback_main"
|
||||
|
||||
expect(
|
||||
setPendingModelFallback(sessionID, "Sisyphus (Ultraworker)", "anthropic", "claude-opus-4-6-thinking"),
|
||||
setPendingModelFallback(sessionID, "Sisyphus - Ultraworker", "anthropic", "claude-opus-4-6-thinking"),
|
||||
).toBe(true)
|
||||
|
||||
const firstOutput = {
|
||||
@@ -154,7 +154,7 @@ describe("model fallback hook", () => {
|
||||
|
||||
//#when - second error re-arms fallback and should advance to next entry
|
||||
expect(
|
||||
setPendingModelFallback(sessionID, "Sisyphus (Ultraworker)", "anthropic", "claude-opus-4-6"),
|
||||
setPendingModelFallback(sessionID, "Sisyphus - Ultraworker", "anthropic", "claude-opus-4-6"),
|
||||
).toBe(true)
|
||||
|
||||
const secondOutput = {
|
||||
@@ -181,13 +181,13 @@ describe("model fallback hook", () => {
|
||||
//#when
|
||||
const firstSet = setPendingModelFallback(
|
||||
sessionID,
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"anthropic",
|
||||
"claude-opus-4-6-thinking",
|
||||
)
|
||||
const secondSet = setPendingModelFallback(
|
||||
sessionID,
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"anthropic",
|
||||
"claude-opus-4-6-thinking",
|
||||
)
|
||||
@@ -218,7 +218,7 @@ describe("model fallback hook", () => {
|
||||
expect(
|
||||
setPendingModelFallback(
|
||||
sessionID,
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"anthropic",
|
||||
"claude-opus-4-6",
|
||||
),
|
||||
@@ -262,7 +262,7 @@ describe("model fallback hook", () => {
|
||||
expect(
|
||||
setPendingModelFallback(
|
||||
sessionID,
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"quotio",
|
||||
"claude-opus-4-6",
|
||||
),
|
||||
@@ -308,7 +308,7 @@ describe("model fallback hook", () => {
|
||||
expect(
|
||||
setPendingModelFallback(
|
||||
sessionID,
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"provider-x",
|
||||
"current-model",
|
||||
),
|
||||
@@ -348,7 +348,7 @@ describe("model fallback hook", () => {
|
||||
|
||||
const set = setPendingModelFallback(
|
||||
"ses_model_fallback_toast",
|
||||
"Sisyphus (Ultraworker)",
|
||||
"Sisyphus - Ultraworker",
|
||||
"anthropic",
|
||||
"claude-opus-4-6-thinking",
|
||||
)
|
||||
@@ -389,7 +389,7 @@ describe("model fallback hook", () => {
|
||||
|
||||
const set = setPendingModelFallback(
|
||||
sessionID,
|
||||
"Atlas (Plan Executor)",
|
||||
"Atlas - Plan Executor",
|
||||
"github-copilot",
|
||||
"claude-sonnet-4-5",
|
||||
)
|
||||
|
||||
@@ -54,11 +54,11 @@ export function createNoHephaestusNonGptHook(
|
||||
if (allowNonGptModel) {
|
||||
return
|
||||
}
|
||||
input.agent = SISYPHUS_DISPLAY
|
||||
input.agent = "sisyphus"
|
||||
if (output?.message) {
|
||||
output.message.agent = SISYPHUS_DISPLAY
|
||||
output.message.agent = "sisyphus"
|
||||
}
|
||||
updateSessionAgent(input.sessionID, SISYPHUS_DISPLAY)
|
||||
updateSessionAgent(input.sessionID, "sisyphus")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ describe("no-hephaestus-non-gpt hook", () => {
|
||||
|
||||
// then - toast is shown and agent is switched to sisyphus
|
||||
expect(showToast).toHaveBeenCalledTimes(2)
|
||||
expect(output1.message.agent).toBe(SISYPHUS_DISPLAY)
|
||||
expect(output2.message.agent).toBe(SISYPHUS_DISPLAY)
|
||||
expect(output1.message.agent).toBe("sisyphus")
|
||||
expect(output2.message.agent).toBe("sisyphus")
|
||||
expect(showToast.mock.calls[0]?.[0]).toMatchObject({
|
||||
body: {
|
||||
title: "NEVER Use Hephaestus with Non-GPT",
|
||||
@@ -141,6 +141,6 @@ describe("no-hephaestus-non-gpt hook", () => {
|
||||
|
||||
// then - toast shown via session-agent fallback, switched to sisyphus
|
||||
expect(showToast).toHaveBeenCalledTimes(1)
|
||||
expect(output.message.agent).toBe(SISYPHUS_DISPLAY)
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -43,11 +43,11 @@ export function createNoSisyphusGptHook(ctx: PluginInput) {
|
||||
|
||||
if (agentKey === "sisyphus" && modelID && isGptModel(modelID) && !isGpt5_4Model(modelID)) {
|
||||
showToast(ctx, input.sessionID)
|
||||
input.agent = HEPHAESTUS_DISPLAY
|
||||
input.agent = "hephaestus"
|
||||
if (output?.message) {
|
||||
output.message.agent = HEPHAESTUS_DISPLAY
|
||||
output.message.agent = "hephaestus"
|
||||
}
|
||||
updateSessionAgent(input.sessionID, HEPHAESTUS_DISPLAY)
|
||||
updateSessionAgent(input.sessionID, "hephaestus")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ describe("no-sisyphus-gpt hook", () => {
|
||||
|
||||
// then - toast is shown for every message
|
||||
expect(showToast).toHaveBeenCalledTimes(2)
|
||||
expect(output1.message.agent).toBe(HEPHAESTUS_DISPLAY)
|
||||
expect(output2.message.agent).toBe(HEPHAESTUS_DISPLAY)
|
||||
expect(output1.message.agent).toBe("hephaestus")
|
||||
expect(output2.message.agent).toBe("hephaestus")
|
||||
expect(showToast.mock.calls[0]?.[0]).toMatchObject({
|
||||
body: {
|
||||
title: "NEVER Use Sisyphus with GPT",
|
||||
@@ -131,6 +131,6 @@ describe("no-sisyphus-gpt hook", () => {
|
||||
|
||||
// then - toast shown via session-agent fallback
|
||||
expect(showToast).toHaveBeenCalledTimes(1)
|
||||
expect(output.message.agent).toBe(HEPHAESTUS_DISPLAY)
|
||||
expect(output.message.agent).toBe("hephaestus")
|
||||
})
|
||||
})
|
||||
|
||||
@@ -94,7 +94,7 @@ describe("prometheus-md-only", () => {
|
||||
|
||||
test("should enforce md-only restriction for Prometheus display name Plan Builder", async () => {
|
||||
//#given
|
||||
setupMessageStorage(TEST_SESSION_ID, "Prometheus (Plan Builder)")
|
||||
setupMessageStorage(TEST_SESSION_ID, "Prometheus - Plan Builder")
|
||||
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
||||
const input = {
|
||||
tool: "Write",
|
||||
|
||||
@@ -133,14 +133,14 @@ export function createAutoRetryHelpers(deps: HookDeps) {
|
||||
})
|
||||
|
||||
const retryAgent = resolvedAgent ?? getSessionAgent(sessionID)
|
||||
const retryAgentDisplayName = retryAgent ? getAgentDisplayName(retryAgent) : undefined
|
||||
sessionAwaitingFallbackResult.add(sessionID)
|
||||
scheduleSessionFallbackTimeout(sessionID, retryAgent)
|
||||
|
||||
await ctx.client.session.promptAsync({
|
||||
path: { id: sessionID },
|
||||
body: {
|
||||
...(retryAgentDisplayName ? { agent: retryAgentDisplayName } : {}),
|
||||
// Use config key to avoid HTTP header validation issues with display names
|
||||
...(retryAgent ? { agent: retryAgent } : {}),
|
||||
...retryModelPayload,
|
||||
parts: retryParts,
|
||||
},
|
||||
|
||||
@@ -2458,7 +2458,7 @@ describe("runtime-fallback", () => {
|
||||
|
||||
expect(promptCalls.length).toBe(1)
|
||||
const callBody = promptCalls[0]?.body as Record<string, unknown>
|
||||
expect(callBody?.agent).toBe("Prometheus (Plan Builder)")
|
||||
expect(callBody?.agent).toBe("prometheus")
|
||||
expect(callBody?.model).toEqual({ providerID: "github-copilot", modelID: "claude-opus-4.6" })
|
||||
})
|
||||
})
|
||||
|
||||
@@ -453,7 +453,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
})
|
||||
|
||||
test("should switch to Atlas even when current session is Sisyphus (regression: #3155)", async () => {
|
||||
@@ -473,7 +473,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// atlas is registered in beforeEach, so it must be selected
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(sessionState.getSessionAgent("ses-sisyphus-to-atlas")).toBe("atlas")
|
||||
})
|
||||
|
||||
@@ -496,7 +496,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("Sisyphus (Ultraworker)")
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(sessionState.getSessionAgent("ses-prometheus-to-sisyphus")).toBe("sisyphus")
|
||||
})
|
||||
|
||||
@@ -524,7 +524,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("Sisyphus (Ultraworker)")
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(sessionState.getSessionAgent("ses-prometheus-to-worker")).toBe("sisyphus")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("sisyphus")
|
||||
})
|
||||
@@ -559,7 +559,7 @@ You are starting a Sisyphus work session.
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe("Sisyphus (Ultraworker)")
|
||||
expect(output.message.agent).toBe("sisyphus")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("sisyphus")
|
||||
})
|
||||
|
||||
@@ -594,7 +594,7 @@ You are starting a Sisyphus work session.
|
||||
await atlasHook.handler({ event: { type: "session.idle", properties: { sessionID: "session-123" } } })
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(readBoulderState(testDir)?.session_ids).toContain("session-123")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("atlas")
|
||||
expect(promptAsyncMock).toHaveBeenCalledTimes(1)
|
||||
@@ -684,7 +684,7 @@ You are starting a Sisyphus work session.
|
||||
await firePendingTimers()
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(readBoulderState(testDir)?.session_ids).toContain("session-123")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("atlas")
|
||||
expect(promptAsyncMock).toHaveBeenCalledTimes(1)
|
||||
|
||||
@@ -85,12 +85,12 @@ export function createStartWorkHook(ctx: PluginInput) {
|
||||
const activeAgent = isAgentRegistered("atlas")
|
||||
? "atlas"
|
||||
: "sisyphus"
|
||||
const activeAgentDisplayName = activeAgent === "atlas"
|
||||
? getAgentListDisplayName(activeAgent)
|
||||
: getAgentDisplayName(activeAgent)
|
||||
const activeAgentDisplayName = getAgentDisplayName(activeAgent)
|
||||
updateSessionAgent(input.sessionID, activeAgent)
|
||||
if (output.message) {
|
||||
output.message["agent"] = activeAgentDisplayName
|
||||
// Use config key for agent field to avoid HTTP header validation issues
|
||||
// Display names like "Atlas (Plan Executor)" contain parens that are invalid in headers
|
||||
output.message["agent"] = activeAgent
|
||||
}
|
||||
|
||||
const existingState = readBoulderState(ctx.directory)
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("injectContinuation", () => {
|
||||
ctx: ctx as never,
|
||||
sessionID: "ses_display_name_agent",
|
||||
resolvedInfo: {
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
model: { providerID: "anthropic", modelID: "claude-sonnet-4-20250514" },
|
||||
},
|
||||
sessionStateStore: sessionStateStore as never,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const PARENTHETICAL_SUFFIX_PATTERN = /\s*(\([^)]*\)\s*)+$/u
|
||||
const DASH_SUFFIX_PATTERN = /\s+-\s+.+$/u
|
||||
const ZERO_WIDTH_CHARACTERS_PATTERN = /[\u200B\u200C\u200D\uFEFF]/g
|
||||
|
||||
export function normalizeProtectedAgentName(agentName: string): string {
|
||||
@@ -7,6 +8,7 @@ export function normalizeProtectedAgentName(agentName: string): string {
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(PARENTHETICAL_SUFFIX_PATTERN, "")
|
||||
.replace(DASH_SUFFIX_PATTERN, "")
|
||||
.replace(/[-_]/g, "")
|
||||
.trim()
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ describe("createPluginInterface - command.execute.before", () => {
|
||||
)
|
||||
|
||||
// then
|
||||
expect(output.message.agent).toBe(getAgentListDisplayName("atlas"))
|
||||
expect(output.message.agent).toBe("atlas")
|
||||
expect(getSessionAgent("ses-command-atlas")).toBe("atlas")
|
||||
expect(readBoulderState(testDir)?.agent).toBe("atlas")
|
||||
})
|
||||
|
||||
@@ -87,7 +87,7 @@ describe("createChatMessageHandler - /start-work integration", () => {
|
||||
await handler(input, output)
|
||||
|
||||
// then
|
||||
expect(output.message["agent"]).toBe("Sisyphus (Ultraworker)")
|
||||
expect(output.message["agent"]).toBe("sisyphus")
|
||||
expect(output.parts[0].text).toContain("<auto-slash-command>")
|
||||
expect(output.parts[0].text).toContain("Auto-Selected Plan")
|
||||
expect(output.parts[0].text).toContain("boulder.json has been created")
|
||||
@@ -397,7 +397,7 @@ describe("createChatMessageHandler - TUI variant passthrough", () => {
|
||||
//#then
|
||||
expect(output.message["model"]).toBeUndefined()
|
||||
expect(getSessionModel("test-session")).toEqual({ providerID: "openai", modelID: "gpt-5.4" })
|
||||
expect(getSessionAgent("test-session")).toBe("Prometheus (Plan Builder)")
|
||||
expect(getSessionAgent("test-session")).toBe("Prometheus - Plan Builder")
|
||||
})
|
||||
|
||||
test("respects a mid-conversation model switch instead of reusing the previous stored model", async () => {
|
||||
|
||||
@@ -92,8 +92,8 @@ describe("createEventHandler - model fallback", () => {
|
||||
parentID: "msg_user_1",
|
||||
modelID: "claude-opus-4-6-thinking",
|
||||
providerID: "anthropic",
|
||||
mode: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
mode: "Sisyphus - Ultraworker",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
cost: 0,
|
||||
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
||||
@@ -184,7 +184,7 @@ describe("createEventHandler - model fallback", () => {
|
||||
content: [],
|
||||
modelID: "claude-opus-4-6-thinking",
|
||||
providerID: "anthropic",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
},
|
||||
},
|
||||
@@ -246,7 +246,7 @@ describe("createEventHandler - model fallback", () => {
|
||||
role: "user",
|
||||
modelID: "claude-opus-4-6-thinking",
|
||||
providerID: "anthropic",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -314,7 +314,7 @@ describe("createEventHandler - model fallback", () => {
|
||||
role: "user",
|
||||
modelID: "claude-opus-4-6",
|
||||
providerID: "quotio",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -395,7 +395,7 @@ describe("createEventHandler - model fallback", () => {
|
||||
content: [],
|
||||
modelID: "claude-opus-4-6",
|
||||
providerID: "quotio",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
},
|
||||
},
|
||||
@@ -597,7 +597,7 @@ describe("createEventHandler - model fallback", () => {
|
||||
parentID: "msg_user_disabled_1",
|
||||
modelID: "claude-opus-4-6-thinking",
|
||||
providerID: "anthropic",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
cost: 0,
|
||||
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
|
||||
|
||||
@@ -771,7 +771,7 @@ describe("createEventHandler - retry dedupe lifecycle", () => {
|
||||
role: "user",
|
||||
modelID: "claude-opus-4-6-thinking",
|
||||
providerID: "anthropic",
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -255,7 +255,7 @@ async function primeMainSession(
|
||||
content: [],
|
||||
modelID: PRIMARY_MODEL.modelID,
|
||||
providerID: PRIMARY_MODEL.providerID,
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
},
|
||||
},
|
||||
@@ -337,7 +337,7 @@ async function triggerAssistantMessageError(
|
||||
model: PRIMARY_MODEL_STRING,
|
||||
modelID: PRIMARY_MODEL.modelID,
|
||||
providerID: PRIMARY_MODEL.providerID,
|
||||
agent: "Sisyphus (Ultraworker)",
|
||||
agent: "Sisyphus - Ultraworker",
|
||||
path: { cwd: "/tmp", root: "/tmp" },
|
||||
error: {
|
||||
statusCode: 529,
|
||||
|
||||
@@ -174,7 +174,7 @@ describe("resolveUltraworkOverride", () => {
|
||||
const output = createOutput("ulw do something")
|
||||
|
||||
//#when
|
||||
const result = resolveUltraworkOverride(config, "Sisyphus (Ultraworker)", output)
|
||||
const result = resolveUltraworkOverride(config, "Sisyphus - Ultraworker", output)
|
||||
|
||||
//#then
|
||||
expect(result).toEqual({ providerID: "anthropic", modelID: "claude-opus-4-6", variant: "max" })
|
||||
@@ -408,7 +408,7 @@ describe("applyUltraworkModelOverrideOnMessage", () => {
|
||||
const tui = createMockTui()
|
||||
|
||||
//#when
|
||||
applyUltraworkModelOverrideOnMessage(config, "Sisyphus (Ultraworker)", output, tui)
|
||||
applyUltraworkModelOverrideOnMessage(config, "Sisyphus - Ultraworker", output, tui)
|
||||
|
||||
//#then
|
||||
expect(dbOverrideSpy).toHaveBeenCalledWith(
|
||||
|
||||
@@ -92,12 +92,12 @@ describe("Agent Config Integration", () => {
|
||||
const displayNames = agents.map((agent) => getAgentDisplayName(agent))
|
||||
|
||||
// then - display names are correct
|
||||
expect(displayNames).toContain("Sisyphus (Ultraworker)")
|
||||
expect(displayNames).toContain("Hephaestus (Deep Agent)")
|
||||
expect(displayNames).toContain("Prometheus (Plan Builder)")
|
||||
expect(displayNames).toContain("Atlas (Plan Executor)")
|
||||
expect(displayNames).toContain("Metis (Plan Consultant)")
|
||||
expect(displayNames).toContain("Momus (Plan Critic)")
|
||||
expect(displayNames).toContain("Sisyphus - Ultraworker")
|
||||
expect(displayNames).toContain("Hephaestus - Deep Agent")
|
||||
expect(displayNames).toContain("Prometheus - Plan Builder")
|
||||
expect(displayNames).toContain("Atlas - Plan Executor")
|
||||
expect(displayNames).toContain("Metis - Plan Consultant")
|
||||
expect(displayNames).toContain("Momus - Plan Critic")
|
||||
expect(displayNames).toContain("oracle")
|
||||
expect(displayNames).toContain("librarian")
|
||||
expect(displayNames).toContain("explore")
|
||||
@@ -112,12 +112,12 @@ describe("Agent Config Integration", () => {
|
||||
const displayNames = keys.map((key) => getAgentDisplayName(key))
|
||||
|
||||
// then - correct display names are returned
|
||||
expect(displayNames[0]).toBe("Sisyphus (Ultraworker)")
|
||||
expect(displayNames[1]).toBe("Atlas (Plan Executor)")
|
||||
expect(displayNames[2]).toBe("Sisyphus (Ultraworker)")
|
||||
expect(displayNames[3]).toBe("Atlas (Plan Executor)")
|
||||
expect(displayNames[4]).toBe("Prometheus (Plan Builder)")
|
||||
expect(displayNames[5]).toBe("Prometheus (Plan Builder)")
|
||||
expect(displayNames[0]).toBe("Sisyphus - Ultraworker")
|
||||
expect(displayNames[1]).toBe("Atlas - Plan Executor")
|
||||
expect(displayNames[2]).toBe("Sisyphus - Ultraworker")
|
||||
expect(displayNames[3]).toBe("Atlas - Plan Executor")
|
||||
expect(displayNames[4]).toBe("Prometheus - Plan Builder")
|
||||
expect(displayNames[5]).toBe("Prometheus - Plan Builder")
|
||||
})
|
||||
|
||||
test("returns original key for unknown agents", () => {
|
||||
@@ -189,8 +189,8 @@ describe("Agent Config Integration", () => {
|
||||
const prometheusDisplay = getAgentDisplayName("prometheus")
|
||||
|
||||
// then - display names are correct
|
||||
expect(sisyphusDisplay).toBe("Sisyphus (Ultraworker)")
|
||||
expect(prometheusDisplay).toBe("Prometheus (Plan Builder)")
|
||||
expect(sisyphusDisplay).toBe("Sisyphus - Ultraworker")
|
||||
expect(prometheusDisplay).toBe("Prometheus - Plan Builder")
|
||||
|
||||
// then - config values are preserved
|
||||
expect(result.migrated.sisyphus).toEqual({ model: "anthropic/claude-opus-4-6", temperature: 0.1 })
|
||||
@@ -218,8 +218,8 @@ describe("Agent Config Integration", () => {
|
||||
const atlasDisplay = getAgentDisplayName("atlas")
|
||||
|
||||
// then - display names are correct
|
||||
expect(sisyphusDisplay).toBe("Sisyphus (Ultraworker)")
|
||||
expect(atlasDisplay).toBe("Atlas (Plan Executor)")
|
||||
expect(sisyphusDisplay).toBe("Sisyphus - Ultraworker")
|
||||
expect(atlasDisplay).toBe("Atlas - Plan Executor")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,8 +9,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Sisyphus (Ultraworker)"
|
||||
expect(result).toBe("Sisyphus (Ultraworker)")
|
||||
// then returns "Sisyphus - Ultraworker"
|
||||
expect(result).toBe("Sisyphus - Ultraworker")
|
||||
})
|
||||
|
||||
it("returns display name for uppercase config key (old format - case-insensitive)", () => {
|
||||
@@ -20,8 +20,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Sisyphus (Ultraworker)" (case-insensitive lookup)
|
||||
expect(result).toBe("Sisyphus (Ultraworker)")
|
||||
// then returns "Sisyphus - Ultraworker" (case-insensitive lookup)
|
||||
expect(result).toBe("Sisyphus - Ultraworker")
|
||||
})
|
||||
|
||||
it("returns original key for unknown agents (fallback)", () => {
|
||||
@@ -42,8 +42,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Atlas (Plan Executor)"
|
||||
expect(result).toBe("Atlas (Plan Executor)")
|
||||
// then returns "Atlas - Plan Executor"
|
||||
expect(result).toBe("Atlas - Plan Executor")
|
||||
})
|
||||
|
||||
it("returns display name for prometheus", () => {
|
||||
@@ -53,8 +53,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Prometheus (Plan Builder)"
|
||||
expect(result).toBe("Prometheus (Plan Builder)")
|
||||
// then returns "Prometheus - Plan Builder"
|
||||
expect(result).toBe("Prometheus - Plan Builder")
|
||||
})
|
||||
|
||||
it("returns display name for sisyphus-junior", () => {
|
||||
@@ -75,8 +75,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Metis (Plan Consultant)"
|
||||
expect(result).toBe("Metis (Plan Consultant)")
|
||||
// then returns "Metis - Plan Consultant"
|
||||
expect(result).toBe("Metis - Plan Consultant")
|
||||
})
|
||||
|
||||
it("returns display name for momus", () => {
|
||||
@@ -86,8 +86,8 @@ describe("getAgentDisplayName", () => {
|
||||
// when getAgentDisplayName called
|
||||
const result = getAgentDisplayName(configKey)
|
||||
|
||||
// then returns "Momus (Plan Critic)"
|
||||
expect(result).toBe("Momus (Plan Critic)")
|
||||
// then returns "Momus - Plan Critic"
|
||||
expect(result).toBe("Momus - Plan Critic")
|
||||
})
|
||||
|
||||
it("returns display name for oracle", () => {
|
||||
@@ -137,17 +137,17 @@ describe("getAgentDisplayName", () => {
|
||||
|
||||
describe("getAgentConfigKey", () => {
|
||||
it("resolves display name to config key", () => {
|
||||
// given display name "Sisyphus (Ultraworker)"
|
||||
// given display name "Sisyphus - Ultraworker"
|
||||
// when getAgentConfigKey called
|
||||
// then returns "sisyphus"
|
||||
expect(getAgentConfigKey("Sisyphus (Ultraworker)")).toBe("sisyphus")
|
||||
expect(getAgentConfigKey("Sisyphus - Ultraworker")).toBe("sisyphus")
|
||||
})
|
||||
|
||||
it("resolves display name case-insensitively", () => {
|
||||
// given display name in different case
|
||||
// when getAgentConfigKey called
|
||||
// then returns "atlas"
|
||||
expect(getAgentConfigKey("atlas (plan executor)")).toBe("atlas")
|
||||
expect(getAgentConfigKey("atlas - plan executor")).toBe("atlas")
|
||||
})
|
||||
|
||||
it("passes through lowercase config keys unchanged", () => {
|
||||
@@ -167,11 +167,11 @@ describe("getAgentConfigKey", () => {
|
||||
it("resolves all core agent display names", () => {
|
||||
// given all core display names
|
||||
// when/then each resolves to its config key
|
||||
expect(getAgentConfigKey("Hephaestus (Deep Agent)")).toBe("hephaestus")
|
||||
expect(getAgentConfigKey("Prometheus (Plan Builder)")).toBe("prometheus")
|
||||
expect(getAgentConfigKey("Atlas (Plan Executor)")).toBe("atlas")
|
||||
expect(getAgentConfigKey("Metis (Plan Consultant)")).toBe("metis")
|
||||
expect(getAgentConfigKey("Momus (Plan Critic)")).toBe("momus")
|
||||
expect(getAgentConfigKey("Hephaestus - Deep Agent")).toBe("hephaestus")
|
||||
expect(getAgentConfigKey("Prometheus - Plan Builder")).toBe("prometheus")
|
||||
expect(getAgentConfigKey("Atlas - Plan Executor")).toBe("atlas")
|
||||
expect(getAgentConfigKey("Metis - Plan Consultant")).toBe("metis")
|
||||
expect(getAgentConfigKey("Momus - Plan Critic")).toBe("momus")
|
||||
expect(getAgentConfigKey("Sisyphus-Junior")).toBe("sisyphus-junior")
|
||||
})
|
||||
|
||||
@@ -182,10 +182,10 @@ describe("getAgentConfigKey", () => {
|
||||
|
||||
describe("getAgentListDisplayName", () => {
|
||||
it("applies invisible stable-sort prefixes to the core agent list", () => {
|
||||
expect(getAgentListDisplayName("sisyphus")).toBe("\u200BSisyphus (Ultraworker)")
|
||||
expect(getAgentListDisplayName("hephaestus")).toBe("\u200B\u200BHephaestus (Deep Agent)")
|
||||
expect(getAgentListDisplayName("prometheus")).toBe("\u200B\u200B\u200BPrometheus (Plan Builder)")
|
||||
expect(getAgentListDisplayName("atlas")).toBe("\u200B\u200B\u200B\u200BAtlas (Plan Executor)")
|
||||
expect(getAgentListDisplayName("sisyphus")).toBe("\u200BSisyphus - Ultraworker")
|
||||
expect(getAgentListDisplayName("hephaestus")).toBe("\u200B\u200BHephaestus - Deep Agent")
|
||||
expect(getAgentListDisplayName("prometheus")).toBe("\u200B\u200B\u200BPrometheus - Plan Builder")
|
||||
expect(getAgentListDisplayName("atlas")).toBe("\u200B\u200B\u200B\u200BAtlas - Plan Executor")
|
||||
})
|
||||
|
||||
it("keeps non-core agents unprefixed for list display", () => {
|
||||
@@ -195,16 +195,16 @@ describe("getAgentListDisplayName", () => {
|
||||
|
||||
describe("normalizeAgentForPrompt", () => {
|
||||
it("strips core UI ordering prefixes back to canonical display names", () => {
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("sisyphus"))).toBe("Sisyphus (Ultraworker)")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("hephaestus"))).toBe("Hephaestus (Deep Agent)")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("prometheus"))).toBe("Prometheus (Plan Builder)")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("atlas"))).toBe("Atlas (Plan Executor)")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("sisyphus"))).toBe("Sisyphus - Ultraworker")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("hephaestus"))).toBe("Hephaestus - Deep Agent")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("prometheus"))).toBe("Prometheus - Plan Builder")
|
||||
expect(normalizeAgentForPrompt(getAgentListDisplayName("atlas"))).toBe("Atlas - Plan Executor")
|
||||
})
|
||||
})
|
||||
|
||||
describe("normalizeAgentForPromptKey", () => {
|
||||
it("converts built-in display names to config keys", () => {
|
||||
expect(normalizeAgentForPromptKey("Sisyphus (Ultraworker)")).toBe("sisyphus")
|
||||
expect(normalizeAgentForPromptKey("Sisyphus - Ultraworker")).toBe("sisyphus")
|
||||
})
|
||||
|
||||
it("preserves custom agents", () => {
|
||||
@@ -216,15 +216,15 @@ describe("AGENT_DISPLAY_NAMES", () => {
|
||||
it("contains all expected agent mappings", () => {
|
||||
// given expected mappings
|
||||
const expectedMappings = {
|
||||
sisyphus: "Sisyphus (Ultraworker)",
|
||||
hephaestus: "Hephaestus (Deep Agent)",
|
||||
prometheus: "Prometheus (Plan Builder)",
|
||||
atlas: "Atlas (Plan Executor)",
|
||||
sisyphus: "Sisyphus - Ultraworker",
|
||||
hephaestus: "Hephaestus - Deep Agent",
|
||||
prometheus: "Prometheus - Plan Builder",
|
||||
atlas: "Atlas - Plan Executor",
|
||||
"sisyphus-junior": "Sisyphus-Junior",
|
||||
metis: "Metis (Plan Consultant)",
|
||||
momus: "Momus (Plan Critic)",
|
||||
athena: "Athena (Council)",
|
||||
"athena-junior": "Athena-Junior (Council)",
|
||||
metis: "Metis - Plan Consultant",
|
||||
momus: "Momus - Plan Critic",
|
||||
athena: "Athena - Council",
|
||||
"athena-junior": "Athena-Junior - Council",
|
||||
oracle: "oracle",
|
||||
librarian: "librarian",
|
||||
explore: "explore",
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
* Display names include suffixes for UI/logs (e.g., "Sisyphus (Ultraworker)").
|
||||
*/
|
||||
export const AGENT_DISPLAY_NAMES: Record<string, string> = {
|
||||
sisyphus: "Sisyphus (Ultraworker)",
|
||||
hephaestus: "Hephaestus (Deep Agent)",
|
||||
prometheus: "Prometheus (Plan Builder)",
|
||||
atlas: "Atlas (Plan Executor)",
|
||||
sisyphus: "Sisyphus - Ultraworker",
|
||||
hephaestus: "Hephaestus - Deep Agent",
|
||||
prometheus: "Prometheus - Plan Builder",
|
||||
atlas: "Atlas - Plan Executor",
|
||||
"sisyphus-junior": "Sisyphus-Junior",
|
||||
metis: "Metis (Plan Consultant)",
|
||||
momus: "Momus (Plan Critic)",
|
||||
athena: "Athena (Council)",
|
||||
"athena-junior": "Athena-Junior (Council)",
|
||||
metis: "Metis - Plan Consultant",
|
||||
momus: "Momus - Plan Critic",
|
||||
athena: "Athena - Council",
|
||||
"athena-junior": "Athena-Junior - Council",
|
||||
oracle: "oracle",
|
||||
librarian: "librarian",
|
||||
explore: "explore",
|
||||
|
||||
@@ -675,7 +675,7 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
|
||||
})
|
||||
const args = createBaseArgs({ subagent_type: "\\hephaestus\\" })
|
||||
const executorCtx = createExecutorContext(async () => ([
|
||||
{ name: "Hephaestus (Deep Agent)", mode: "subagent", model: "openai/gpt-5.3-codex" },
|
||||
{ name: "Hephaestus - Deep Agent", mode: "subagent", model: "openai/gpt-5.3-codex" },
|
||||
]))
|
||||
|
||||
//#when
|
||||
@@ -683,7 +683,7 @@ describe("resolveSubagentExecution - agent name sanitization", () => {
|
||||
|
||||
//#then
|
||||
expect(result.error).toBeUndefined()
|
||||
expect(result.agentToUse).toBe("Hephaestus (Deep Agent)")
|
||||
expect(result.agentToUse).toBe("Hephaestus - Deep Agent")
|
||||
cacheSpy.mockRestore()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user